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

时间:2015-09-10 05:57:04

标签: javascript typescript

有没有办法在TypeScript中嵌套类。例如。我想像使用它们一样使用它们:

var foo = new Foo();
var bar = new Foo.Bar();

7 个答案:

答案 0 :(得分:86)

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

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

class Foo {
    static Bar = class {

    }
}

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

答案 1 :(得分:14)

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

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

codepen

答案 2 :(得分:11)

我无法使用导出的类而不会收到编译错误,而是使用namespaces

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

答案 3 :(得分:7)

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

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

答案 4 :(得分:0)

这个答案是关于 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 Fooexport { 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()

答案 5 :(得分:0)

希望能帮到你

能够:

  • 创建一个新的内部类实例
  • 访问外部类实例/原型成员
  • 实现接口
  • 使用装饰器

用例

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

答案 6 :(得分:-6)

这种方法适用于打字稿Angular2 / Ionic2环境。

foo.ts

import { Bar} from './bar';

export class Foo {
    id: number;
    bar: Bar;
}

bar.ts

export class Bar {
    id: number;
}

示例类用法:

foo = new Foo();
foo.bar = new Bar();
foo.bar.id = 1;