'new'表达式,其目标在TypeScript中缺少构造签名

fuz*_*uzz 19 javascript typescript

我们有以下TestComponent.tsTypeScript类:

01: import TestVectorLayer from './TestVectorLayer'
02: 
03: export class TestComponent implements OnInit {
04:   private foo: any;
05: 
06:   constructor() { }
07: 
08:   const layer = new TestVectorLayer("foo");
09: }
Run Code Online (Sandbox Code Playgroud)

并具有以下TestVectorLayer.ts功能:

请记住,OpenLayer 3正在使用Google Closure库,这就是为什么TestVectorLayer它不是TypeScript类.

01: declare let ol: any;
02:
03: const TestVectorLayer = function (layerName: string) {
04:   ...
05:   console.log(layerName);
06:
07:   ol.layer.Image.call(this, opts);
08: }
09:
10: ol.inherits(TestVectorLayer as any, ol.layer.Image as any);
11:
12: export default TestVectorLayer; 
Run Code Online (Sandbox Code Playgroud)

我们收到以下错误:

Error on Line 08 in TestComponent.ts class:
Run Code Online (Sandbox Code Playgroud)

[ts]'new'表达式,其目标缺少构造签名,隐式具有"any"类型.导入TestVectorLayer

package.jsonTypeScript 的版本:

devDependencies:

"typescript": "~2.2.1"
Run Code Online (Sandbox Code Playgroud)

Dav*_*ret 22

这是问题的简化:

const TestVectorLayer = function(layerName: string) {
};

const layer = new TestVectorLayer("");
Run Code Online (Sandbox Code Playgroud)

发生错误是因为TestVectorLayer没有新签名,因此layer隐式输入any.那个错误--noImplicitAny.

您可以通过切换到类来解决这个问题,但在您的情况下,这看起来有点复杂,因为继承是由底层框架完成的.因此,你将不得不做一些更复杂的事情,这并不理想:

interface TestVectorLayer {
  // members of your "class" go here
}

const TestVectorLayer = function (this: TestVectorLayer, layerName: string) {
  // ...
  console.log(layerName);
  ol.layer.Image.call(this, opts);
} as any as { new (layerName: string): TestVectorLayer; };

ol.inherits(TestVectorLayer, ol.layer.Image);

export default TestVectorLayer; 
Run Code Online (Sandbox Code Playgroud)

然后在文件中TestComponent:

const layer = new TestVectorLayer(layerName); // no more compile error
Run Code Online (Sandbox Code Playgroud)

  • @SohelAhmedM在[此处](https://basarat.gitbooks.io/typescript/docs/types/type-assertion.html)阅读有关类型断言的信息。as as是对any类型的类型断言。将value与T一样做是两种类型的断言,并且是在无法将value的类型断言为T时(例如,将value作为T的断言)将value类型断言为T的一种方式。 `会导致编译错误,但是您想以任何方式声明它。本质上,这是绕过类型检查器的一种方法。 (2认同)
  • 一定喜欢打字稿。为了弄清楚这些东西浪费了多少时间? (2认同)

Mar*_*ski 10

David的回答很好,但是如果您只关心快速进行编译(例如,因为您正在从JS迁移到TS),那么您可以简单地放在any那里以关闭抱怨的编译器。

TS文件:

const TestConstructorFunction = function (this: any, a: any, b: any) {
    this.a = a;
    this.b = b;
};

let test1 = new (TestConstructorFunction as any)(1, 2);
Run Code Online (Sandbox Code Playgroud)

编译为此JS文件:

var TestConstructor = function (a, b) {
    this.a = a;
    this.b = b;
};
var test1 = new TestConstructor(1, 2);
Run Code Online (Sandbox Code Playgroud)

请注意不要犯以下错误:

TS文件:

// wrong!
let test2 = new (TestConstructorFunction(1, 2) as any);
Run Code Online (Sandbox Code Playgroud)

JS结果:

// wrong!
var test2 = new (TestConstructor(1, 2));
Run Code Online (Sandbox Code Playgroud)

这是错误的。您将TypeError: TestConstructor(...) is not a constructor在运行时出错。

  • 非常感谢,它有效!`const s1 = new (学生作为任何)('精英', 23);` (3认同)
  • @Onkeltem 是的,我也很惊讶它得到了更多的喜欢。好吧,人们希望修复编译器错误并继续前进。我不能责怪他们。我想这比根本不使用 Typescript 好;-) 接受的答案显然更好,因为它为函数提供了正确的类型定义,因此在所有“new FunCtr(...)”调用时都会进行类型检查。但如果你只需要修复一个被调用的地方那么我认为这没什么大不了的。IMO 使用 `as any` 通常应该被认为是不好的做法,但有时你只是想关闭编译器并继续...... (2认同)