typescript - utsøkt typekontroll i IF-setning
Jeg leste om uttømmende typetesting, og det er virkelig en flott funksjon i TypeScript. Jeg eksperimenterte med det og støtte på noen merkelig oppførsel (eller ikke fullt implementert av TypeScript-teamet). Dette er koden jeg har nå (som fungerer utmerket):
type factType = 'test-1' | 'test-2'
function doSomething(fact: factType) {
if (fact ==='test-1') {
return true;
} else if(fact === 'test-2') {
return true;
}
assertUnreachable(fact);
}
function assertUnreachable(x: never): never {
throw new Error("Didn't expect to get here");
}
Men når jeg bruker en funksjon som en forgreningsbetingelse, bryter det. Det sier "Argument av typen 'string' kan ikke tildeles parameteren av typen 'never' faktum: "test-2""
type factType = 'test-1' | 'test-2';
function doSomething(fact: factType) {
if (fact === 'test-1') {
return true;
} else if (isTest2(fact)) {
return true;
}
assertUnreachable(fact);
}
function isTest2(fact: factType) {
return fact === 'test-2';
}
Jeg prøvde å bruke fact as 'test-2', men det fungerer ikke. Er det noen som vet hvordan man fikser dette eller hva årsaken kan være? Jeg tror det er Typescript, men jeg er på ingen måte en ekspert!
Takk!
Svar #1
Bruk en typepredikat for å indikere for TS at funksjonen sjekker om fact er av typen test-2.
function isTest2(fact: factType): fact is 'test-2' {
return fact === 'test-2';
}
Svar #2
Jeg er også ganske ny på uttømmende sjekking, men mesteparten av tiden ser jeg det i kombinasjon med switch-tilfellet. Følgende eksempel fungerer:
type factType = 'test-1' | 'test-2';
function doSomething(fact: factType): boolean {
switch (fact) {
case 'test-1':
return true;
case 'test-2':
return true;
default:
assertUnreachable(fact);
}
}
Jeg antar at når du bruker en funksjon som kan ta enten 'test-1' eller 'test-2', er det ikke det samme som å bruke case der bare én verdi for factType kan evalueres om gangen. Ved å bruke union (|) sier du "factType kan bare være en av disse typene. Enten den ene eller den andre." assertUnreachable vil sørge for at alle mulige veier dekkes ved kompilering (hurra!). Dette betyr at hvis factType skulle få en tilleggstype, vil assertUnreachable gi en kompilasjonsfeil.
Å legge til en ny type resulterer i kompileringfeil
type factType = 'test-1' | 'test-2' | 'test-3';
function doSomethingElse(fact: factType): boolean {
switch (fact) {
case 'test-1':
return true;
case 'test-2':
return false;
default:
assertUnreachable(fact); // TS2345: Argument of type '"test-3"' is not assignable to parameter of type 'never'
}
