声明合并继承的类命名空间中的接口

时间:2016-06-15 21:39:14

标签: typescript

这似乎不在手册中。

我很好奇为什么没有合并在单独但继承的类名称空间中具有相同名称的接口。下面的示例显示第二个界面隐藏第一个界面而不是与其合并。由于继承的命名空间的成员是可见的,我的直觉是认为接口将被合并。我意识到我可以明确声明Bar.IOptions扩展Foo.IOptions,我只是想知道当前行为是否符合预期?

class Foo {
    constructor(options: Foo.IOptions = {}) {
        this._a = options.a || 0;
    }
    private _a: number;
}


namespace Foo {
    export interface IOptions {
        a?: number;
    }

    export const c = 12;
}


class Bar extends Foo {
    constructor(options: Bar.IOptions) {
        super();
        this._b = options.b;  // okay
        this._c = Bar.c;      // okay, inherited from Foo
        this._a2 = options.a; // fail
    }

    private _b: string;
    private _c: number;
    private _a2: number;
}


namespace Bar {
    export interface IOptions {
        b?: string;
    }
}

1 个答案:

答案 0 :(得分:1)

这是因为完全限定的名称不同 - 一个是Foo.IOptions,另一个是Bar.IOptions

请注意,声明合并仅在具有相同的完全限定名称时才会发生:

namespace Foo {
    export interface IOptions {
        a?: number;
    }
}

namespace Foo {
    export interface IOptions {
        b?: string;
    }
}

var options: Foo.IOptions = {};
options.a; // works
options.b; // works

另外,要意识到FooBar的构造函数采用不同的类型。 Foo需要Foo.IOptionsBar需要Bar.IOptions

您无法传递Foo类型为Bar.IOptions的对象...

class Bar extends Foo {
    constructor(options: Bar.IOptions) {
        super(options); // doesn't work
    }
}

...但你可以传递一个Foo.IOptions ...

的对象
class Bar extends Foo {
    constructor(options: Bar.IOptions) {
        super({ a: 5 }); // works
    }
}