Person & Serializable & Loggable est une personne et Serializable et Loggable.
Cela signifie qu'un objet de ce type aura tous les membres des trois types.mixin et d'autres concepts qui ne rentrent pas dans le moule classique orienté objet.
( Il y en a beaucoup en JavaScript ! ).mixin :number ou un string.padLeft est que son paramètre padding est tapé comme any.
Cela signifie que nous pouvons l'appeler avec un argument qui n'est ni un number ni un string, mais TypeScript l'acceptera.padLeft est que nous n'avons pu passer que des primitives.
Cela signifiait que l'utilisation était simple et concise.
Cette nouvelle approche ne nous aiderait pas non plus si nous essayions simplement d'utiliser une fonction qui existe déjà ailleurs.any, nous pouvons utiliser un type d'union pour le paramètre padding :|) pour séparer chaque type, de même que number | string | boolean le type d'une valeur qui peut être a number,
a string ou a boolean.A | B, nous savons seulement avec certitude qu'elle a des membres qui ont tous les deux A et B.
Dans cet exemple, Bird est membre est nommé fly.
Nous ne pouvons pas être sûrs qu'une variable typée Bird | Fish a une méthode fly.
Si la variable est vraiment un Fish à l'exécution, l'appel pet.fly() échouera.Fish ?
Un langage courant JavaScript pour différencier deux valeurs possibles la solution est de vérifier la présence d'un membre.
Comme nous l'avons mentionné, vous ne pouvez accéder qu'aux membres dont il est garanti qu'ils appartiennent à tous les groupes constitutifs d'un type syndical.pet.TypeScript a quelque chose appelé un type guard.
Un type guard est une expression qui effectue une vérification à l'exécution qui garantit le type dans une certaine portée.
Pour définir une protection de type, nous devons simplement définir une fonction dont le type de retour est un prédicat de type :pet is Fish est notre prédicat de type dans cet exemple.
Un prédicat prend la forme parameterName is Type, où parameterName doit être le nom d'un paramètre de la signature de la fonction actuelle.isFish appelé avec une variable, TypeScript restreindra cette variable à ce type spécifique si le type d'origine est compatible.TypeScript non seulement sait que pet est un Fish dans la branche; il sait aussi que dans la branche else,
vous n'avez un Fish, vous devez donc un BirdpadLeft qui utilise des types d'union.
Nous pourrions l'écrire avec les prédicats de type comme suit :typeof x === "number" dans sa propre fonction car TypeScript le reconnaîtra comme un garde de type.
Cela signifie que nous pourrions simplement écrire ces chèques en ligne.typeof sont reconnus sous deux formes différentes :
typeof v === "typename" et typeof v !== "typename" où "typename" doit être "number", "string", "boolean" ou "symbol".
Bien que TypeScript ne vous empêche pas de comparer d'autres chaînes, le langage ne reconnaît pas ces expressions en tant que gardes du type.typeof les polices de caractères et connaissez instanceof de l'opérateur JavaScript,
vous avez probablement une idée de ce à quoi sert cette section.instanceof permettent de réduire les types à l'aide de leur fonction constructeur.
Prenons, par exemple, notre exemple de dépisteur de cordes industriel :instanceof doit être une fonction constructeur, et TypeScript se limitera à :prototype de la fonction si son type n'est pas anyTypeScript a deux types spéciaux, null et undefined, qui ont respectivement les valeurs null et indéfinie.
Nous en avons parlé brièvement dans la section Types de base.
Par défaut, le vérificateur de type considère null et peut être undefined assigné à quoi que ce soit.
Effectivement, null et undefined sont des valeurs valides de chaque type.
Cela signifie qu'il n'est pas possible d'empêcher leur assignation à quelque type que ce soit, même si vous souhaitez l'empêcher.
L'inventeur de null Tony Hoare appelle cela "son erreur d'un milliard de dollars".--strictNullChecks corrige ceci : lorsque vous déclarez une variable, elle n'inclut pas automatiquement null ni undefined.
Vous pouvez les inclure explicitement en utilisant un type d'union :TypeScript traite null et undefined différemment afin de correspondre à la sémantique JavaScript.
string | null est un type différent de string | undefined et string | undefined | null.--strictNullChecks, un paramètre optionnel ajoute automatiquement | undefined :guard pour vous en débarrasser null.
Heureusement, c'est le même code que vous écriviez en JavaScript :null est assez évidente ici, mais vous pouvez aussi utiliser des opérateurs de terser :null ou undefined, vous pouvez utiliser l'opérateur d'assertion de type pour les supprimer manuellement.
La syntaxe est postfix ! : identifier! supprime null et undefined du type de identifier :interfaced dans un éditeur montrera qu'il retourne un Interface,
mais montrera que aliased retourne le type littéral d'objet.TypeScript a aussi des types littéraux numériques.x doit être 1 quand il est comparé à 2,
ce qui signifie que la vérification ci-dessus fait une comparaison invalide.enum et aux types littéraux numériques / chaînes,
même si de nombreux utilisateurs utiliseront indifféremment les "types singleton" et les "types littéraux".TypeScript s'appuie sur les modèles JavaScript tels qu'ils existent aujourd'hui. Triangle à Shape, nous devons également mettre à jour area :--strictNullChecks et à spécifier un type de retour :switch n'est plus exhaustif, TypeScript est conscient que la fonction peut parfois être retournée undefined.
Si vous avez un type de retour explicite number, vous obtiendrez une erreur indiquant que le type de retour est réellement number | undefined.
Cependant, cette méthode est assez subtile et --strictNullChecks ne fonctionne pas toujours avec l'ancien code.never, utilisé par le compilateur pour vérifier l'exhaustivité :assertNever contrôles s de type never, le type qui reste après la suppression de tous les autres cas.
Si vous oubliez un cas, vous saurez un type réel et vous obtiendrez une erreur de type.
Cette méthode nécessite de définir une fonction supplémentaire, mais c'est beaucoup plus évident quand vous l'oubliez.this polymorphe représente un type qui est le sous type de la classe ou de l'interface qui le contient.
Ceci est appelé polymorphisme lié à F. Cela rend les interfaces fluides hirarchiques beaucoup plus faciles à exprimer, par exemple.
Prenons une simple calculatrice qui retourne this après chaque opération :
this, ScientificCalculator n'aurait pas été en mesure d'étendre BasicCalculator et de maintenir l'interface fluide.
multiply serait retourné BasicCalculator, qui n'a pas la méthode sin.
Cependant, avec les types this, les retours multiply this, ce qui est ScientificCalculator ici.
Javascript courant consiste à choisir un sous-ensemble de propriétés dans un objet :TypeScript, à l'aide de la requête de type d'index et des opérateurs d'accès indexés :name s'agit bien d'une propriété Person.
L'exemple introduit quelques nouveaux opérateurs de type.
Le premier est keyof T l'opérateur de requête de type index.
Pour tout type T, keyof T est l'union des noms de propriété publique connus de T.keyof Person est complètement interchangeable avec 'name' | 'age'.
La différence est que si vous ajoutez une autre propriété à Person, par exemple address : string,
elle keyof Person sera automatiquement mise à jour 'name' | 'age' | 'address'.
Et vous pouvez utiliser keyof des contextes génériques tels que pluck,
où vous ne pouvez pas connaître les noms de propriété à l'avance.
Cela signifie que le compilateur vérifiera que vous transmettez le bon ensemble de noms de propriétés à pluck :T[K] l'opérateur d'accès indexé.
Ici, la syntaxe de type reflète la syntaxe d'expression.
Cela signifie que cela person['name'] a le type Person['name'] ce qui dans notre exemple est juste string.
Cependant, tout comme les requêtes de type index, vous pouvez utiliser T[K] un contexte générique, où son pouvoir réel prend vie.
Vous devez juste vous assurer que le type variable K extends keyof T. Voici un autre exemple avec une fonction nommée getProperty.getProperty, o: T et name: K, donc ça veut dire o[name]: T[K].
Une fois que vous avez renvoyé le résultat T[K], le compilateur instancie le type actuel de la clé.
Le type de retour getProperty varie en fonction de la propriété que vous demandez.keyof et T[K] interagir avec les signatures d'index de chaîne.
Si vous avez un type avec une signature d'index de chaîne, ce keyof T sera juste string.
Et T[string] est juste le type de la signature d'index :Javascript que TypeScript offre un moyen de créer de nouveaux types basés sur d'anciens types - types mappés.
Dans un type mappé, le nouveau type transforme chaque propriété de l'ancien type de la même manière.
Par exemple, vous pouvez rendre toutes les propriétés d'un type readonly ou facultatives.for .. in intérieur. Il y a trois parties :K, qui est liée à chaque propriété.Keys, qui contient les noms des propriétés à itérer.Keys est une liste codée en dur de noms de propriétés et le type de propriété est toujours boolean,
de sorte que ce type mappé est équivalent à l'écriture :Readonly ou Partial dépassent.
Ils sont basés sur un type existant et transforment les propriétés d'une manière ou d'une autre.
C'est là que keyof interviennent les types d'accès indexés :keyof T et le type résultant est une variante de T[P].
C'est un bon modèle pour toute utilisation générale des types mappés.
En effet, ce type de transformation est homomorphique, ce qui signifie que le mappage s'applique uniquement aux propriétés des T autres propriétés.
Le compilateur sait qu'il peut copier tous les modificateurs de propriétés existants avant d'en ajouter de nouveaux.
Par exemple, si Person.name était en lecture seule, Partial‹Person›.name serait en lecture seule et facultatif.T[P] est encapsulé dans une classe Proxy‹T› :Readonly‹T› et Partial‹T› sont très utiles, ils sont inclus dans la bibliothèque standard de TypeScript avec Picket Record :Readonly, Partial et Pick sont homomorphic alors que Record ne l'est pas.
Un indice qui Record n'est pas homomorphe est qu'il ne faut pas un type d'entrée pour copier les propriétés de :TypeScript 2.8 introduit des types conditionnels qui permettent d'exprimer des mappages de types non uniformes.
Un type conditionnel sélectionne l'un des deux types possibles en fonction d'une condition exprimée sous la forme d'un test de relation de type :T est assignable au U type est X, sinon le type est Y.T extends U ? X : Y est résolu en X ou Y,
ou différé car la condition dépend d'une ou de plusieurs variables de type.
Lorsque T ou U contient des variables de type, la résolution en X ou Y,
ou en différé, est déterminée par le fait que le système de types possède suffisamment d'informations pour conclure qu'il T est toujours assignable U.TypeName de type, qui utilise des types conditionnels imbriqués :a a un type conditionnel qui n'a pas encore choisi de branche.
Quand un autre morceau de code finit par appeler foo, il sera remplacé U par un autre type et TypeScript réévaluera le type conditionnel,
en décidant s'il peut réellement choisir une branche.U extends Foo ? string : number à, string | number peu importe ce que le
conditionnel évalue, il est connu pour être l'un string ou l'autre number.T extends U ? X : Y avec l'argument type A | B | C pour T est résolue
en tant que (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).T extends U ? X : Y, les références au T type conditionnel sont
résolues en constituants individuels du type union (c'est-à- dire, T fait référence aux constituants individuels une fois que
le type conditionnel est distribué sur le type union). De plus, les références à T inside X ont une contrainte de paramètre de
type supplémentaire U (c'est-à-dire T qu'elles sont assignables à U dedans X).T a la contrainte supplémentaire any[] dans la branche vraie de Boxed‹T› et il est donc possible de se référer au type
d'élément du tableau comme T[number]. Notez également comment le type conditionnel est distribué sur le type d'union dans le dernier exemple.extends d'un type conditionnel, il est maintenant possible d'avoir des déclarations qui introduisent une variable de type à inférer.
De telles variables de type inféré peuvent être référencées dans la branche vraie du type conditionnel. Il est possible d'avoir plusieurs
inferemplacements pour la même variable de type.TypeScript 2.8 ajoute plusieurs types conditionnels prédéfinis à lib.d.ts:Exclude‹T, U› - Exclure de T ces types qui sont assignables à U.Extract‹T, U› - Extrait de T ces types qui sont assignables à U.NonNullable‹T› - Exclure null et undefined de T.ReturnType‹T› - Obtenir le type de retour d'un type de fonction.InstanceType‹T› - Obtenir le type d'instance d'un type de fonction constructeur.Exclude correspond à une implémentation appropriée du type Diff suggéré ici.
Nous avons utilisé le nom Exclude pour éviter de casser le code existant qui définit un Diff,
et nous pensons que ce nom véhicule mieux la sémantique du type. Nous n'avons pas inclus le Omit‹T, K› type car il
est écrit trivialement comme Pick‹T, Exclude‹keyof T, K››.