接口定义如下:
interface IRemoteService {
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>>;
}
interface ICreateResponse<T> {
createdId: T;
}
为什么以下代码不会导致Typescript编译错误?
class RemoteServiceMock implements IRemoteService {
public static $inject = ["$q"];
constructor(private $q: ng.IQService){
}
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>> {
return this.$q.when({});
}
}
$q.when
的类型为when<T>(value: T): IPromise<T>
。
答案 0 :(得分:3)
这是根据规范。以下是您简化的示例:
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
将type参数用作成员,则会出错:
interface IPromise<T>{
member:T
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // Error
在实际的承诺定义中,我们有类似的东西:
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
,B
将由bivariance进行类型检查。因此,如果A是B的子集,或者B是A的子集,则它们是兼容的。
答案 1 :(得分:1)
我不确定为什么你没有收到错误,但我确实对如何得到警告提出了建议。根据angular.d.ts when
定义如下:
when<T>(value: IPromise<T>): IPromise<T>;
when<T>(value: T): IPromise<T>;
when(): IPromise<void>;
因此,如果您想使用when
进行更多输入,请使用:
return this.$q.when<ICreateResponse<string>>({});