Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript库定义文件中的命名构造函数和嵌套类型-";重复标识符“;错误_Typescript - Fatal编程技术网

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

TypeScript库定义文件中的命名构造函数和嵌套类型-";重复标识符“;错误,typescript,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 ty

我正在尝试为现有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;  
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 }
    }
}
我让它处理嵌套类和接口,但是由于某种原因,当我试图声明嵌套枚举时,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
中进行注释,编译器就会在变量声明行中给出重复的标识符“SomeClass”。这是一个编译器错误(我使用的是0.9.1.1),因为编译器认为它必须创建一个声明,因为枚举常量还是我做错了什么

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

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


1嗯,我不得不重命名接口以使用后缀,但这至少可以工作,并且不会影响行为)。我无法让它使用与模块和变量声明相同的名称来处理接口,尽管从我的理解来看,这实际上应该是可行的。不过,在我的所有测试中,它都没有出现。

您可以这样建模:

var enumValue = MyModule.SomeClass.SomeEnum.VALUE_A;  
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 }
    }
}

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

您可以这样建模:

var enumValue = MyModule.SomeClass.SomeEnum.VALUE_A;  
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 }
    }
}

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

这似乎满足了您的要求:

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
上创建错误:
错误:(13,26)TS2305:模块“MyModule”没有导出的成员“SomeClass”。

对于命名构造函数,它也可能不完美。
我对命名构造函数的理解不够,无法判断这一点。

这似乎满足了您的要求:

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
上创建错误:
错误:(13,26)TS2305:模块“MyModule”没有导出的成员“SomeClass”。

对于命名构造函数,它也可能不完美。
我对命名构造函数的理解不够,无法判断这一点。

我没有尝试混合枚举成员和构造。我在类中寻找嵌套枚举,就像在您的示例中一样,它似乎工作得很好!起初我放弃了这种方法,因为不幸的是WebStorm 7.0.2现在确实在这种语法上有一些问题,hower tsc.exe很高兴,VS也很高兴,所以我可以针对WS!谢谢!我不能让它与泛型一起工作。(这就是我最初放弃这种方法的原因,IIRC)。只要我希望
SomeClass
是泛型的,类/模块方法就不再适用于我了。对于那些阅读本文的人,我发布了OK,这实际上是0.9.1.1中的一个bug,并且在更新的(beta)版本中得到了修复。我没有尝试混合枚举成员和构造。我在类中寻找嵌套枚举,就像在您的示例中一样,它似乎工作得很好!起初我放弃了这种方法,因为不幸的是WebStorm 7.0.2现在确实在这种语法上有一些问题,hower tsc.exe很高兴,VS也很高兴,所以我可以针对WS!谢谢!我不能让它与泛型一起工作。(这就是我最初放弃这种方法的原因,IIRC)。只要我希望
SomeClass
是泛型的,类/模块方法就不再适用于我了。我发布了OK,对于阅读本文的人来说,这实际上是0.9.1.1中的一个bug,并且在较新的(beta版)版本中得到了修复。