Typescript:使用静态内部类的类型
Posted
技术标签:
【中文标题】Typescript:使用静态内部类的类型【英文标题】:Typescript: Using the type of a static inner class 【发布时间】:2017-03-17 18:00:26 【问题描述】:我正在尝试编写一个向其消费者公开内部数据结构的类,该类本身将使用的数据结构。
例子:
class Outer
static Inner = class
inInner: number
;
constructor(public inner: Outer.Inner)
这里的问题是Outer.Inner
没有被识别为类型。
我找到的唯一答案是workarounds (in Typescript playground)。我想知道是否有任何优雅的方法可以做到这一点。
用例:
我有一堆通过 WebSockets 在客户端和服务器之间发送的动作。每个Action
都有自己的Data
内部类。 Data
类本身在服务器的其他地方使用。我可以把它分成两个类(或一个接口),比如Action1
、Action1Data
,但我认为Action1.Data
是一个更易读的设计。
【问题讨论】:
【参考方案1】:您的第二个“解决方法”是首选方法:
class Outer
constructor(public inner: Outer.Inner)
namespace Outer
export class Inner
inInner: number
;
// Spec
let outer1 = new Outer( inInner: 3 );
let outerInner = new Outer.Inner();
let outer2 = new Outer(outerInner);
TypeScript 中有三种类型的声明:命名空间、类型和值。
您可以使用namespace
来组织类型和值。
http://www.typescriptlang.org/docs/handbook/declaration-merging.html
它不会降低可读性,因为 TypeScript 中没有“内部类”的概念。
请记住,class
语法只是 es5 原型继承的糖。
您将如何表示原型继承中的内部类?你把它作为一个实例变量吗?或下Outer.prototype.???
它在 es5 中的结果是这样的:
var Outer = function Outer(...) ...
Outer.Inner = function Inner() ...
如果您看一下,Outer.Inner
中的Outer
仅用作保存Inner
类的“命名空间”。
【讨论】:
感谢 Typescript 手册参考!我没有意识到命名空间可以正式用于声明合并。 我使用您提供的解决方案。但是,有一个问题。假设 Outer 类在 ES6 模块中并被导出。但是我们不想导出 Outer.Inner。有可能吗? 由于Inner
被用于Outer
的公共属性中,所以需要将其公开。这个命名空间技巧通过将***类型隐藏在Outer
下来帮助最小化***类型。如果你真的不想暴露它,你可以考虑直接内联你的类型。但也有限制。
这不满足内部类为私有时的情况。
@TomaszGawel 是的,但是如果该类确实是私有的,则不需要公开它。做Outer.Inner =
就是暴露它。【参考方案2】:
我找到了一个更好的解决方法,它甚至允许内部类访问外部类的私有成员,就像您在类 C# 语言中所期望的那样。实际上,您可以使用 typeof
运算符轻松获取静态属性的类型。对您的示例进行的这个小修改有效:
class Outer
static Inner = class
inInner: number = 0;
;
constructor(public inner: typeof Outer.Inner.prototype)
但是将类型称为typeof Outer.Inner.prototype
很快就会变得很麻烦,所以在下面添加它,您可以根据需要简单地将其称为Outer.Inner
:
namespace Outer
export type Inner = typeof Outer.Inner.prototype;
将此与另一种解决方法结合起来,允许我们将装饰器放在类上,使其不是匿名类,最终得到一个功能齐全的真正内部类:
class Outer
static Inner = (() =>
@decoratable()
class OuterInner
inInner: number = 0;
return OuterInner;
)();
constructor(public inner: Outer.Inner)
namespace Outer
export type Inner = typeof Outer.Inner.prototype;
【讨论】:
你也可以使用export type Inner = InstanceType<typeof Outer.Inner>;
以上是关于Typescript:使用静态内部类的类型的主要内容,如果未能解决你的问题,请参考以下文章