Pourquoi le tapuscrit a-t-il un type puis un "type similaire"? Un exemple de ceci est Promise<T>
et PromiseLike<T>
. Quelles sont les différences entre ces deux types? Quand dois-je les utiliser? Dans ce cas, pourquoi ne pas avoir un seul type Promise
?
Réponse
Trop de publicités?Si vous regardez les fichiers de définition (prenons lib.es6.d.ts) ensuite c'est assez simple.
Par exemple, le ArrayLike interface:
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
est plus limité que le Tableau d' un:
interface Array<T> {
length: number;
toString(): string;
toLocaleString(): string;
push(...items: T[]): number;
pop(): T | undefined;
concat(...items: T[][]): T[];
concat(...items: (T | T[])[]): T[];
join(separator?: string): string;
reverse(): T[];
shift(): T | undefined;
slice(start?: number, end?: number): T[];
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number): T[];
splice(start: number, deleteCount: number, ...items: T[]): T[];
unshift(...items: T[]): number;
indexOf(searchElement: T, fromIndex?: number): number;
lastIndexOf(searchElement: T, fromIndex?: number): number;
// lots of other methods such as every, forEach, map, etc
[n: number]: T;
}
Il est bon d'avoir les deux séparés, car j'aimerais avoir une fonction comme ceci:
function getSize(arr: Array<any>): number {
return arr.length;
}
console.log(getSize([1, 2, 3])); // works
Mais il ne fonctionne pas avec ceci:
function fn() {
console.log(getSize(arguments)); // error
}
C'résultats avec cette erreur:
Argument de type 'IArguments" n'est pas assignable à paramètre de type "toute[]'.
Propriété "push" est manquant dans le "type de IArguments'.
Mais les deux ne fonctionnera que si je fais ceci:
function getSize(arr: ArrayLike<any>): number {
return arr.length;
}
(plus sur ArrayLike dans MDN)
De même avec Promise
et PromiseLike
, si je suis en train de construire une bibliothèque qui n'est pas d'opinions à propos de la mise en œuvre de l' Promise
alors au lieu de faire ceci:
function doSomething(promise: Promise<any>) { ... }
Je vais le faire:
function doSomething(promise: PromiseLike<any>) { ... }
Alors, même si l'utilisateur de ma bibliothèque est à l'aide d'une mise en œuvre différente (bluebird), cela fonctionnera très bien.
Si vous remarquerez la définition de la Promesse est ceci:
declare var Promise: PromiseConstructor;
Ce qui le rend très spécifiques, d'autres implémentations peuvent avoir des propriétés différentes, par exemple un autre prototype:
interface PromiseConstructor {
readonly prototype: Promise<any>;
...
}
Je pense que la principale raison pour laquelle nous avons PromiseLike
, c'est que plusieurs implémentations sont disponibles avant que le natif a été pris en charge ( bluebird, des Promesses/A+, jQuery, et plus).
Pour que la machine fonctionne avec des bases de code qui sont à l'aide de ces mises en oeuvre, il doit être d'un type autre que Promise
, sinon il y aurait beaucoup de contradictions.