With interfaces defined like so:
interface IRemoteService {
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>>;
}
interface ICreateResponse<T> {
createdId: T;
}
Why doesn't the following code cause a Typescript compilation error?
class RemoteServiceMock implements IRemoteService {
public static $inject = ["$q"];
constructor(private $q: ng.IQService){
}
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>> {
return this.$q.when({});
}
}
The type of $q.when is when<T>(value: T): IPromise<T>.
This is according to spec. Here is your example simplified:
interface A{
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // No error
This assignment is allowed if A is a subtype of B or B is a subtype of A. If this is not the case you will get an error as shown below:
interface A {
breakTypeCompat: number;
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // Error
The reason is the bivariance compatibility of function arguments. See this link for docs + reason why this is the way it is: https://github.com/Microsoft/TypeScript/wiki/Type-Compatibility#function-argument-bivariance
Type compatibility of the interfaces depends upon how you use them. E.g. the following is not an error :
interface IPromise<T>{
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // No error
However if the IPromise where to use the type parameter as a member it would error:
interface IPromise<T>{
member:T
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // Error
In the actual promise definition we have something like:
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
Since we are using T as an argument to the a function A and B will be type checked by bivariance. So if A is a subset of B or B is a subset of A they are compatible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With