Typescript 构造函数接口:没有匹配构造函数的类仍然是可赋值的
假设我们有一个接口,它定义了构造函数应该接受的参数:Typescript 构造函数接口:没有匹配构造函数的类仍然是可赋值的,typescript,Typescript,假设我们有一个接口,它定义了构造函数应该接受的参数: interface Ctr { new (num: number): any; } 然后我们有一个具有默认构造函数的类: class DefCtr { } 然后,出于某种原因,我可以将DefCtr类分配给Ctr类型的变量: const Instance: Ctr = DefCtr; const i = new Instance(1); console.log(i); // The output is: // DefCtr {}
interface Ctr {
new (num: number): any;
}
然后我们有一个具有默认构造函数的类:
class DefCtr {
}
然后,出于某种原因,我可以将DefCtr
类分配给Ctr
类型的变量:
const Instance: Ctr = DefCtr;
const i = new Instance(1);
console.log(i);
// The output is:
// DefCtr {}
因此,实例
是一个DefCtr
类(没有构造函数接受编号)。但接口迫使我在创建它的实例时传递一个数字(将被忽略)
有趣的是,只有当类具有默认构造函数时,它才起作用。例如,这将不起作用:
interface Ctr {
new (num: number): any;
}
class NotDefCtr {
// Lets create a non-default constructor
constructor(str: string) {
}
}
const Instance: Ctr = NotDefCtr; // Error:
// Type 'typeof NotDefCtr' is not assignable to type 'Ctr'.
// Types of parameters 'str' and 'num' are incompatible.
// Type 'number' is not assignable to type 'string'.
错误是有道理的。但在我看来,在尝试使用默认构造函数分配类时收到错误也是有意义的(因为它没有任何其他构造函数匹配接口)。TypeScript常见问题解答有一个条目:。这是相同的问题,除了使用newable而不是callable。我将把这个条目翻译成这个例子: 这是预期和期望的行为。有一种说法是,如果一个对象
X
可以用来代替某个对象Y
,那么X
就是Y
的一个子类型或可分配给Y
在这种情况下,DefCtr
是Ctr
的一个子类型,因为DefCtr
的构造函数可以安全地忽略额外的number
参数。但是NotDefCtr
不是Ctr
的子类型,因为NotDefCtr
的类型表示它需要string
类型的参数;数字
不能安全地用作字符串
,因此它不兼容
(旁白:事实证明,NotDefCtr
的构造函数实际上忽略了它的输入,因此在运行时不会发生爆炸。但是类型系统并不关心构造函数的具体实现;它看到一个合同的签名,上面说NotDefCtr
的构造函数有权期望一个参数f typestring
。因此用NotDefCtr
替换Ctr
仍然是一个错误)
好的,希望这有帮助;祝你好运!Read;这是同一个问题,除了使用newable而不是普通callable。谢谢你的评论。这很有意义……我认为这可能是答案而不是评论。一个被接受的答案。