我正在尝试编写一个向其使用者公开内部数据结构的类,这是一个类本身将使用的数据结构。
示例:
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
是一个更易读的设计。
答案 0 :(得分:8)
你的第二个"解决方法"是最好的选择:
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原型继承的糖。
你如何代表原型继承的内在阶级?你把is作为实例变量吗?或在Outer.prototype.???
它在es5中的结果是这样的:
var Outer = function Outer(...) { ... }
Outer.Inner = function Inner() { ... }
如果您查看它,Outer
中的Outer.Inner
仅作为"命名空间"持有Inner
班。
答案 1 :(得分:0)
我为此找到了一个更好的解决方法,它甚至允许内部类访问外部类的私有成员,就像您希望使用的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;
}