您可以在TypeScript中创建嵌套类吗?


Answers:


131

从TypeScript 1.6开始,我们有了类表达式(reference)。

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

class Foo {
    static Bar = class {

    }
}

// works!
var foo = new Foo();
var bar = new Foo.Bar();

1
此示例在打字稿1.6.3中不起作用:错误TS4028导出类的公共静态属性“ Bar”具有或正在使用私有名称“(匿名类)”。
谢尔盖(Sergey)2015年

1
@Sergey我遇到了同样的问题,因此按照下面的答案开始使用名称空间。
丹防守

有没有一种方法可以在类内部创建接口?即,如果我们希望Bar成为接口
RoG,

@LittaHervi-一个用例是从例如工厂方法返回外部接口的私有实现。Java(和其他应用程序)中的另一个示例是迭代器,它们需要特权访问其包含类的成员变量,并且通过作用域规则自动进行访问,但是您永远不希望直接导出和实例化这些实例。
戴夫

30

这是使用类表达式的更复杂的用例。

它允许内部类访问外部类private成员

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());

码笔


3
@RyanCavanaugh访问“内部”类表达式内的私有成员的功能是否是错误?
bnieland '17

5
我验证了TypeScript团队的正确用法。 github.com/Microsoft/TypeScript/issues/...
bnieland

1
是否可以在不直接传递父上下文的情况下访问父上下文?
shabunc

@shabunc据我所知
bnieland

1
正是我要的东西,谢谢!
菲利普

19

我无法在不接收编译错误的情况下将其与导出的类一起使用,而是使用了命名空间

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

相同。“ Foo”仅指一种类型,但在此处被用作命名空间。
Will Beason

12

如果您在类型声明文件的上下文中,则可以通过混合类和名称空间来做到这一点:

// 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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.