TypeScript库定义文件中的命名构造函数和嵌套类型 - “重复标识符”错误

时间:2013-12-02 13:55:29

标签: typescript

我正在尝试为现有的Javascript库创建一个TypeScript库定义文件。特别具有挑战性的是我们在库和嵌套类型中都有“命名构造函数”。

在Javascript中你可以这样做,例如:

var some = new MyModule.SomeClass();  //some is of type 'MyModule.SomeClass'
var some2 = new MyModule.SomeClass.WithValue("value"); //some2 is of the same type as some

当类中定义了内部枚举时会出现问题:

var enumValue = MyModule.SomeClass.SomeEnum.VALUE_A;  

我使用嵌套类和接口,但是由于某些原因,当我尝试声明嵌套枚举时,typescript编译器会发生阻塞。这就是我在某些dummylib.d.ts文件中对上述场景的看法:

declare module MyModule {
    export interface SomeClass_Interface {
        foo: number;
    }

    export module SomeClass {
        export interface InnerClass { bar: string; }
        //enum SomeEnum { VALUE_A, B, C }
    }

    export var SomeClass: {
        new (): MyModule.SomeClass_Interface;
        WithValue: {
            new (bar: string): MyModule.SomeClass_Interface;
        };
    };
}

以上工作很好 1 并编译,但是一旦我在SomeEnum中发表评论,编译器就会在变量声明的行中给出Duplicate identifier 'SomeClass'。这是一个编译器错误(我使用0.9.1.1),因为编译器认为它必须创建一个声明,因为枚举常量或我做错了什么?

如何编写定义文件以支持嵌套类型/命名构造函数和嵌套枚举?

请注意,此问题专门针对库定义。我不打算用typescript创建这样的新类,我想使用现有的库而不能修改它。

1 好吧,我不得不重命名接口以使用后缀,但这至少有效并且不影响行为)。我无法使用与模块和变量声明相同的名称来使用接口,尽管根据我对this discussion的理解,这应该可行。但是,在我的所有测试中都没有。

2 个答案:

答案 0 :(得分:4)

你可以这样建模:

declare module MyModule {
    export class SomeClass {
        static WithValue: {
            new (bar: string): SomeClass;
        };
    }

    export module SomeClass {
        export interface InnerClass { bar: string; }
        export enum SomeEnum { VALUE_A, B, C }
    }
}

不幸的是,没有任何其他方法可以使用枚举成员和构造签名来建模对象。

答案 1 :(得分:0)

这似乎符合您的要求:

drwxr-----

这一切都有效:

declare module MyModule {
    export interface SomeClass_Interface {
        foo: number;
    }

    interface InnerClass { bar: string; }

    export class SomeClass implements SomeClass_Interface {
        foo: number;
        public static WithValue(bar: string): void;
        public static SomeEnum: { VALUE_A, B, C };
        public static InnerClass: InnerClass;
        // this works, too (no need for extra interface):
        // public static InnerClass: { bar: string; };
    }
}

不幸的是,这不是:

var some1: MyModule.SomeClass = new MyModule.SomeClass();
var some2: MyModule.SomeClass = new MyModule.SomeClass.WithValue("value");
var enumValue = MyModule.SomeClass.SomeEnum.VALUE_A;
var stringValue: string = MyModule.SomeClass.InnerClass.bar;
var numberValue1: number = some1.foo;
var numberValue2: number = some2.foo;

它会在var enumValue2: MyModule.SomeClass.SomeEnum; 上生成错误:SomeClass

关于命名构造函数,它也可能不完美。 我不太了解命名的构造函数来判断这一点。