【发布时间】:2015-12-06 06:51:35
【问题描述】:
有没有办法在 TypeScript 中嵌套类。例如。我想像这样使用它们:
var foo = new Foo();
var bar = new Foo.Bar();
【问题讨论】:
-
对于较旧的 typescript (Any way to nest classes in typescript?
标签: javascript typescript
有没有办法在 TypeScript 中嵌套类。例如。我想像这样使用它们:
var foo = new Foo();
var bar = new Foo.Bar();
【问题讨论】:
标签: javascript typescript
在现代 TypeScript 中,我们有可以用来创建嵌套类的类表达式。例如,您可以执行以下操作:
class Foo {
static Bar = class {
}
}
// works!
var foo = new Foo();
var bar = new Foo.Bar();
【讨论】:
这是一个使用类表达式的更复杂的用例。
它允许内部类访问外部类的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());
【讨论】:
() => new class一样使用它
如果没有收到编译错误,我无法让它与导出的类一起使用,而是使用namespaces:
namespace MyNamespace {
export class Foo { }
}
namespace MyNamespace.Foo {
export class Bar { }
}
【讨论】:
如果你在一个类型声明文件的上下文中,你可以通过混合类和命名空间来做到这一点:
// 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();
【讨论】:
这个答案是关于 TypeScript 中的一个无缝嵌套类实现,它建立在 @basarat 的答案之上。
要使 static 嵌套类Bar 的类型可访问(正如@PeterMoore 指出的那样),请在命名空间中声明嵌套类的类型。这样,我们可以使用快捷方式Foo.Bar。通过将类型 typeof Foo.Bar.prototype 移动到已声明命名空间中的类型中,我们不必重复表达式。
class Foo {
static Bar = class {
}
}
declare namespace Foo {
type Bar = typeof Foo.Bar.prototype
}
// Now we are able to use `Foo.Bar` as a type
let bar: Foo.Bar = new Foo.Bar()
对于静态类,下面的实现可能更优雅。但是,这不适用于非静态类。
class Foo { }
namespace Foo {
export class Bar { }
}
let bar: Foo.Bar = new Foo.Bar()
要导出类,可以在声明类和命名空间之后添加导出语句,例如export default Foo 或 export { Foo }。
要使用非静态嵌套类实现相同的效果,请参见以下示例。
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()
【讨论】:
希望对你有帮助
能够:
用例
export interface Constructor<T> {
new(...args: any[]): T;
}
export interface Testable {
test(): void;
}
export function LogClassName<T>() {
return function (target: Constructor<T>) {
console.log(target.name);
}
}
class OuterClass {
private _prop1: string;
constructor(prop1: string) {
this._prop1 = prop1;
}
private method1(): string {
return 'private outer method 1';
}
public InnerClass = (
() => {
const $outer = this;
@LogClassName()
class InnerClass implements Testable {
private readonly _$outer: typeof $outer;
constructor(public innerProp1: string) {
this._$outer = $outer;
}
public test(): void {
console.log('test()');
}
public outerPrivateProp1(): string {
return this._$outer._prop1;
}
public outerPrivateMethod1(): string {
return this._$outer.method1();
}
}
return InnerClass;
}
)();
}
const outer = new OuterClass('outer prop 1')
const inner = new outer.InnerClass('inner prop 1');
console.log(inner instanceof outer.InnerClass); // true
console.log(inner.innerProp1); // inner prop 1
console.log(inner.outerPrivateProp1()); // outer prop 1
console.log(inner.outerPrivateMethod1()); // private outer method 1
【讨论】: