/ / Dlaczego ten kod nie powoduje błędu typu TypeScript? - angularjs, maszynopis, maszynopis1.5

Dlaczego ten kod nie powoduje błędu typu TypeScript? - angularjs, maszynopis, maszynopis1.5

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 № 1

Jest 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>>({});