Je me demandais si je pouvais avoir des types conditionnels dans TypeScript?
Actuellement, j'ai l'interface suivante:
interface ValidationResult {
isValid: boolean;
errorText?: string;
}
Mais je veux retirer errorText
, et seulement quand isValid
est false
comme nécessaire la propriété.
J'aimerais pouvoir l'écrire comme l'interface suivante:
interface ValidationResult {
isValid: true;
}
interface ValidationResult {
isValid: false;
errorText: string;
}
Mais comme vous le savez, ce n'est pas possible. Alors, quelle est votre idée de cette situation?
javascript
typescript
types
Arman
la source
la source
isValid
estfalse
?Réponses:
Une façon de modéliser ce type de logique consiste à utiliser un type d'union, quelque chose comme ça
Le compilateur est alors en mesure de restreindre le type en fonction de l'indicateur booléen
la source
r
doit être de typeInvalid
ici.Pour éviter de créer plusieurs interfaces qui ne sont utilisées que pour en créer une troisième, vous pouvez également alterner directement, avec un à la
type
place:la source
L' union démontrée par les bogues est la façon dont je recommande de gérer cela. Néanmoins, Tapuscrit n'ont quelque chose appelé « types conditionnels » , et ils peuvent gérer cela.
Cette
ValidationResult
(qui est en faitValidationResult<boolean>
dû au paramètre par défaut) est équivalent à l'union produite dans la réponse des bogues ou dans la réponse de CertainPerformance , et peut être utilisé de la même manière.L'avantage ici est que vous pouvez également faire circuler une
ValidationResult<false>
valeur connue , et vous n'aurez alors pas à testerisValid
car elle serait connuefalse
eterrorString
existerait. Probablement pas nécessaire pour un cas comme celui-ci - et les types conditionnels peuvent être complexes et difficiles à déboguer, donc ils ne devraient probablement pas être utilisés inutilement. Mais vous le pouviez, et cela semblait utile de le mentionner.la source
extends
est le bon opérateur à utiliser. Et il a très puissant, d' autant plus que vous pouvez également l' utiliser pour creuser dans les types:type SecondOf<T> = T extends Pair<any, infer U> ? U : never;
.SecondOf<number>
«se développe»Pair<any, number>
? Je suppose que le dicton "ne jugez pas un livre par sa couverture" est pertinent ici.SecondOf<Pair<any, number>>
évalue ànumber
.SecondOf<number>
évalue ànever
, parce quenumber extends Pair<any, infer U>
c'est faux, commenumber
ne prolonge aucunPair