TypeScript: hvordan beskytte unions-type med typekontroll
Funksjonen compose kan ha et objekt eller en matrise av objekter som argument. I compose skiller typevakten mellom objektet og matrisen. Funksjonen mapper kan bare håndtere objekter, og ved å bruke typevakten blir bare objekter sendt til den.
interface Link {
something: string;
}
function compose(link: Link|Link[]) {
if (link instanceof Array) {
R.map(function(l) {
return mapper(l);
}, link);
} else {
return mapper(link);
}
}
function mapper(link: Link) {
return link;
}
Kompilering av dette eksemplet resulterer i feilen:
feil TS2345: Argument av typen 'Link | Link[]' kan ikke tildeles parameter av typen 'Link'
Denne feilen er forståelig da mapper får en unionstype som sitt argument, men forventer kun ett enkelt objekt. Dette er ikke det jeg håpet på når jeg brukte type-guard. Noen tanker om dette?
Svar #1
Det ser ut til at TypeScript 1.4.0.0 ikke utleder at link må være av typen Link når det ikke er av typen Array. En liten endring bør løse det:
function compose(link: Link|Link[]) {
if (link instanceof Array) {
R.map(function(l) {
return mapper(l);
}, link);
} else if (link instanceof Link) {
return mapper(link);
}
}
Alternativt kan du angi typen:
return mapper(<Link> link);
