我正在尝试为现有的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的理解,这应该可行。但是,在我的所有测试中都没有。
答案 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
关于命名构造函数,它也可能不完美。 我不太了解命名的构造函数来判断这一点。