打字稿:使用静态内部class的类型

Typescript: Using the type of a static inner class

我正在尝试编写一个 class 向其消费者公开内部数据结构,class 本身将使用的数据结构。

示例:

class Outer {
    static Inner = class {
        inInner: number
    };

    constructor(public inner: Outer.Inner) { }
}

这里的问题是 Outer.Inner 没有被识别为类型。

我找到的唯一答案是 workarounds (in Typescript playground)。我想知道是否有任何优雅的方法可以做到这一点。


用例:

我有一堆在客户端和服务器之间通过 WebSockets 发送的动作。每个 Action 都有自己的 Data 内部 class。 Data class 本身在服务器的其他地方使用。我可以将其分成两个 classes(或接口),例如 Action1Action1Data,但我认为 Action1.Data 是一个更具可读性的设计。

您的第二个“解决方法”是首选方法:

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”的概念。

请记住,class 语法只是 es5 原型继承的糖分。 你会如何在原型继承中表示内部 class ?你把它作为一个实例变量吗?或低于 Outer.prototype.???

它在 es5 中的结果是这样的:

var Outer = function Outer(...) { ... }
Outer.Inner = function Inner() { ... }

如果你看一下,Outer.Inner 中的 Outer 只是作为一个“命名空间”来保存 Inner class.

我找到了一个更好的解决方法,它甚至允许内部 class 访问外部 class 的私有成员,就像您在类 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 来将装饰器放在 class 上,我们最终得到一个功能齐全的真实内部 class:

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;
}