你能在TypeScript中创建嵌套类吗?

bas*_*rat 61 javascript typescript

有没有办法在TypeScript中嵌套类.我想用它们像:

var foo = new Foo();
var bar = new Foo.Bar();
Run Code Online (Sandbox Code Playgroud)

bas*_*rat 94

从TypeScript 1.6开始,我们有类表达式(引用).

这意味着您可以执行以下操作:

class Foo {
    static Bar = class {

    }
}

// works!
var foo = new Foo();
var bar = new Foo.Bar();
Run Code Online (Sandbox Code Playgroud)

  • 有什么办法可以重用父类中的嵌套类吗?类 Foo { 静态 Bar = 类 { }; 字段A:酒吧;//不起作用:找不到名称“Bar”字段B:Foo.Bar; // 不起作用:“Foo”仅引用一个类型,但在这里被用作命名空间。} // 有效!var foo = new Foo(); var bar = new Foo.Bar(); (6认同)
  • 这不允许您在类型注释中使用内部类型。 (4认同)
  • 此示例在 Typescript 1.6.3 中不起作用:错误 TS4028 导出类的公共静态属性“Bar”具有或正在使用私有名称“(匿名类)”。 (2认同)

bni*_*and 16

这是一个使用类表达式的更复杂的用例.它允许内部类访问外部类的私有成员.

class classX { 
    private y: number = 0; 

    public getY(): number { return this.y; }

    public utilities = new class {
        constructor(public superThis: classX) {
        }
        public testSetOuterPrivate(target: number) {
            this.superThis.y = target;
        }
    }(this);    
}

const x1: classX = new classX();

alert(x1.getY());

x1.utilities.testSetOuterPrivate(4);
alert(x1.getY());
Run Code Online (Sandbox Code Playgroud)

codepen

  • @RyanCavanaugh 在“内部”类表达式中访问私有成员的能力是错误​​吗? (4认同)
  • 我验证了TypeScript团队的正确用法。https://github.com/Microsoft/TypeScript/issues/17535#issuecomment-319187970 (2认同)
  • 它是否可以访问父上下文而不直接传递 this ? (2认同)

Dan*_*Def 14

如果没有收到编译错误,我无法使用导出的类,而是使用名称空间:

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}
Run Code Online (Sandbox Code Playgroud)


dan*_*nvk 9

如果您在类型声明文件的上下文中,则可以通过混合类和名称空间来完成此操作:

// foo.d.ts
declare class Foo {
  constructor();
  fooMethod(): any;
}

declare namespace Foo {
  class Bar {
    constructor();
    barMethod(): any;
  }
}

// ...elsewhere
const foo = new Foo();
const bar = new Foo.Bar();
Run Code Online (Sandbox Code Playgroud)


War*_*nio 7

静态嵌套

定义静态嵌套类Foo.Bar可以通过以下两种方式完成。

  1. 选项1:Bar在类内部实现Foo
    该类型在声明中声明declare namespace

    class Foo {
        static Bar = class { }
    }
    
    declare namespace Foo {
        type Bar = typeof Foo.Bar.prototype
    }
    
    let bar: Foo.Bar = new Foo.Bar()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 选项 2:Bar在命名空间内实现Foo
    使用声明合并自动声明类型。

    class Foo { }
    
    namespace Foo {
        export class Bar { }
    }
    
    let bar: Foo.Bar = new Foo.Bar()
    
    Run Code Online (Sandbox Code Playgroud)

非静态嵌套

定义非静态嵌套类Foo.prototype.Bar可以按如下方式完成。该类型在声明中声明declare namespace

class Foo {
    Bar = class { }
}

declare namespace Foo.prototype {
    type Bar = typeof Foo.prototype.Bar.prototype
}

let foo: Foo = new Foo()
let bar: Foo.prototype.Bar = new foo.Bar()
Run Code Online (Sandbox Code Playgroud)

注意:new Foo.prototype.Bar()即使没有类型 声明,它也是有效的 Typescript,但该调用不起作用。