Zastanawiałem się, czy mogę mieć typy warunkowe w TypeScript?
Obecnie mam następujący interfejs:
interface ValidationResult {
isValid: boolean;
errorText?: string;
}
Ale chcę usunąć errorText
i mieć to tylko wtedy, gdy isValid
jest false
to wymagana właściwość.
Chciałbym móc go napisać jako następujący interfejs:
interface ValidationResult {
isValid: true;
}
interface ValidationResult {
isValid: false;
errorText: string;
}
Ale jak wiadomo, nie jest to możliwe. Jaki masz pomysł na tę sytuację?
javascript
typescript
types
Arman
źródło
źródło
isValid
jestfalse
?Odpowiedzi:
Jednym ze sposobów modelowania tego rodzaju logiki jest użycie typu unii, coś takiego
Kompilator może następnie zawęzić typ w oparciu o flagę logiczną
źródło
r
musi być tego typuInvalid
.Aby uniknąć tworzenia wielu interfejsów, które przyzwyczają się tylko do utworzenia trzeciego, możesz również zmienić bezpośrednio
type
:źródło
Unia wykazać błędy sposób obsługi to polecam. Niemniej jednak, maszynopis nie ma czegoś znanego jako „ typy warunkowych ” i można je obsługiwać to.
To
ValidationResult
(co jest tak naprawdęValidationResult<boolean>
spowodowane domyślnym parametrem) jest równoważne związkowi utworzonemu w odpowiedzi na błędy lub w odpowiedzi CertainPerformance i może być używane w ten sam sposób.Zaletą tego jest to, że możesz również przekazywać znaną
ValidationResult<false>
wartość, a wtedy nie będziesz musiał testowaćisValid
tak, jakby był znanyfalse
ierrorString
istniałby. Prawdopodobnie nie jest to konieczne w przypadku tego typu - a typy warunkowe mogą być złożone i trudne do debugowania, więc prawdopodobnie nie należy ich używać niepotrzebnie. Ale mogłeś i to wydawało się warte wspomnienia.źródło
extends
jest właściwym operatorem do użycia. I ma bardzo silny, zwłaszcza, że można również używać go kopać w rodzaju:type SecondOf<T> = T extends Pair<any, infer U> ? U : never;
.SecondOf<number>
„rozszerza się”Pair<any, number>
? Wydaje mi się, że trafne jest powiedzenie „nie oceniaj książki po okładce”.SecondOf<Pair<any, number>>
ocenia nanumber
.SecondOf<number>
ocenianever
, ponieważnumber extends Pair<any, infer U>
jest fałszywy, ponieważnumber
nie rozszerza żadnegoPair