【问题标题】:Assign an ES5 constructor function to a variable of constructor type将 ES5 构造函数分配给构造函数类型的变量
【发布时间】:2022-01-18 22:01:59
【问题描述】:

这段代码有可能存在于 ES5 中并且完美执行:

const ctor = function () {
    return {
        prop: 'value'
    };
};

const obj = new ctor();

console.log(obj);

这是我尝试输入的内容:

interface SomeClass {
    new(...args: any[]): { prop: string };
}

const ctor: SomeClass = function () {
    return {
        prop: 'value'
    };
}

const obj = new ctor();

console.log(obj);

这不会在 TypeScript 中编译,它会抛出:

Type '() => { prop: string; }' is not assignable to type 'SomeClass'.
  Type '() => { prop: string; }' provides no match for the signature 'new (...args: any[]): { prop: string; }'.(2322)

TypeScript 是故意不支持 ES5 语法还是我遗漏了什么?

【问题讨论】:

  • 为什么要添加这个? new(...args: any[])?您正在使用可变参数定义类型中的函数
  • 应该是可以带无参数函数的。顺便说一句,删除并不能解决问题
  • Typescript AFAIK 不支持此功能。 See this
  • @whygee 确实它看起来不受支持

标签: typescript ecmascript-5


【解决方案1】:

问题在于 new() 类型检查是针对类的实例进行的,而构造函数是静态的,它具有不同的类型。更多信息在这里:constructor provides no match for signature new

interface ConstructorInterface {
    new(...args: any[]): SomeOtherInterface
}

interface SomeOtherInterface {
   method(): {prop: string}
}

class Ctor implements SomeOtherInterface {
    method() {
        return {prop: "test"};
    }
}

const obj = new Ctor();
console.log(obj);

这将解决问题,它也可以工作,因为您可以省略构造函数。

您还可以添加一个函数,该函数返回一个实现您的接口的实例。

function createCtor(ctor: ConstructorInterface): SomeOtherInterface {
    return new ctor();
}

const obj1 = createCtor(Ctor);
console.log(obj1);

【讨论】:

  • 在您的示例中,SomeInterface 没有在任何地方使用。当我的问题是关于 ES5 时,您也在使用 ES6 语法
  • 已更新。关于 ES6 语法,其实就是 TypeScript。
  • 所以你是说 TypeScript 不支持 ES5 源代码?
  • 我回答了你用 TypeScript 实现它的问题,这不是你想要的?
  • 让我重新表述我的问题。 TypeScript 是 JavaScript 之上的类型层。我希望它能够输入任何 JavaScript 代码,即使是用 ES5 编写的,但我无法输入 ES5 构造函数。是 TypeScript 不支持的东西还是我做错了?