我有一些通用代码,如下所示:
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()
签名,还是有其他方式表达我的意图?
答案 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