Z interfejsami zdefiniowanymi tak:
interface IRemoteService {
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>>;
}
interface ICreateResponse<T> {
createdId: T;
}
Dlaczego następujący kod nie powoduje błędu kompilacji Maszyny?
class RemoteServiceMock implements IRemoteService {
public static $inject = ["$q"];
constructor(private $q: ng.IQService){
}
createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>> {
return this.$q.when({});
}
}
Typ $q.when
jest when<T>(value: T): IPromise<T>
.
Odpowiedzi:
3 dla odpowiedzi № 1Jest to zgodne ze specyfikacją. Oto uproszczony przykład:
interface A{
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // No error
To przypisanie jest dozwolone, jeśli A jest podtypem B lub B jest podtypem A. Jeśli tak nie jest, otrzymasz błąd, jak pokazano poniżej:
interface A {
breakTypeCompat: number;
}
interface B {
createdId: string;
}
var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // Error
Powodem jest kompatybilność biwariancji argumentów funkcji. Zobacz ten link dla dokumentów + powód, dlaczego tak to wygląda: https://github.com/Microsoft/TypeScript/wiki/Type-Compatibility#function-argument-bivariance
tło
Kompatybilność typów interfejsów zależy od sposobu ich użycia. Na przykład. poniższe nie jest błędem:
interface IPromise<T>{
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // No error
Jednak jeśli IPromise
gdzie użyć parametru type jako członka, spowoduje błąd:
interface IPromise<T>{
member:T
}
interface A{
}
interface B {
createdId: string;
}
var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // Error
W związku z tym
W rzeczywistej definicji obietnicy mamy coś takiego:
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
Ponieważ używamy T
jako argument do a funkcjonować A
i B
zostanie sprawdzony pod kątem biwariancji. Więc jeśli A jest podzbiorem B lub B jest podzbiorem A, są one kompatybilne.
1 dla odpowiedzi nr 2
Nie jestem pewien, dlaczego nie otrzymujesz błędu, ale mam sugestię, jak uzyskać ostrzeżenie. Według kątowych.d.ts when
jest zdefiniowany w następujący sposób:
when<T>(value: IPromise<T>): IPromise<T>;
when<T>(value: T): IPromise<T>;
when(): IPromise<void>;
Więc jeśli chcesz użyć when
więcej pisania na klawiaturze, a następnie użyj:
return this.$q.when<ICreateResponse<string>>({});