这是根据规范。这是您的示例简化:
interface A{
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // No error
如果 A 是 B 的子类型或 B 是 A 的子类型,则允许此分配。如果不是这种情况,您将收到如下所示的错误:
interface A {
breakTypeCompat: number;
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // Error
原因是函数参数的双变量兼容性。请参阅此链接了解文档 + 原因:https ://github.com/Microsoft/TypeScript/wiki/Type-Compatibility#function-argument-bivariance
细节
背景
接口的类型兼容性取决于您如何使用它们。例如,以下不是错误:
interface IPromise<T>{
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // No error
但是,如果IPromise
使用类型参数作为成员的位置会出错:
interface IPromise<T>{
member:T
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // Error
所以
在实际的 Promise 定义中,我们有类似的内容:
interface IPromise<T> {
then(successCallback: (promiseValue: T) => any): any;
}
interface A {
}
interface B {
createdId: string;
}
var foo: IPromise<A>;
var bar: IPromise<B>;
bar = foo; // No Error
由于我们将T
其用作 a函数 A
的参数,并且B
将通过双变量进行类型检查。因此,如果 A 是 B 的子集或 B 是 A 的子集,它们是兼容的。