Function接口是否缺少new()签名?

时间:2014-11-20 22:23:26

标签: typescript

我有一些通用代码,如下所示:

interface IClass<T> {
    new (...args: any[]): T;
}

function someFactory<T>(a: IClass<T>): T {
    return new a();
}

class Foo { }

var f = someFactory(Foo);

f被正确推断为Foo。该函数也不允许使用不可更新的类型。

此外,编译器允许以下内容,f的类型为any

function Foo() { }

var f = new Foo();

所以我希望以下通用代码可以工作:

interface IInstance<T> {
    constructor: IClass<T>;
}

function extractType<T>(a: IInstance<T>): IClass<T> {
    return a.constructor;
}

class Foo { }

var f = new Foo();
var t = extractType(f);

但我在f参数上收到此错误以提取类型:

  

类型'Foo'的参数不能分配给'IInstance&lt; {}&gt;'类型的参数。

如果我放松打字:

function extractType<T extends Object>(a: T): IClass<T> {
    return a.constructor;
}

class Foo { }

var f = new Foo();
var t = extractType(f);

我在a.constructor上收到此错误:

  

类型'函数'不能分配给'IClass'类型。

由于函数是新的,我希望这些模式可以工作。如果我使用new()签名扩展Function接口,它们都可以工作:

interface Function {
    new (...args: any[]): any;
}

那么,Function是否遗漏了new()签名,还是有其他方式表达我的意图?

1 个答案:

答案 0 :(得分:3)

这里的根本原因是TypeScript实际上没有向类实例的对象添加constructor属性。

constructor中使用的extractType属性实际上只是因为属性访问使用操作数的表观类型,这会添加全局接口{{1}的成员到类型。

从技术上讲,这段代码可行,但显然不适用于所有类:

Object

基本上class Foo { 'constructor': typeof Foo; } var f = new Foo(); var t = extractType(f); // t: IClass<Foo> 无法在TypeScript中以一般方式编写,因为构造函数和对象类型之间没有确切的1:1对应关系。你可能有这样的事情:

extractType