javascript - bestem typen til en parameter som kan ha flere typer i typescript


Gitt en funksjon med en parameter av forskjellige typer, hvordan finner jeg ut hvilken type som ble sendt til funksjonen?

Eksempel

interface SomeCustomInterface {
    title: string
}

interface OtherCustomInterface {
    subtitle: string
}


interface A {
    value: string
}

interface B {
    value: number
}

interface C {
    value: SomeCustomInterface
}

interface D {
    value: OtherCustomInterface
}

function doSomething(parameter: A | B | C | D): string {
    switch(parameter.type) { 
        // I know the cases are not valid TS. What should I do instead?
        case A:
            return parameter.value
        case B:
            return parameter.value.toString()
        case C:
            return parameter.value.title
        case D:
            return parameter.value.subtitle
    }
}

Jeg vet at det finnes typevakter, men jeg har bekymringer med dem

  1. De må kunne identifisere hver type unikt. Jeg ser at noen legger til en egenskap kind eller type som gjør at de kan identifisere en type for å kunne beskytte mot feil typetilordning. Dette virker imidlertid som mye ekstra arbeid og oppsett for meg.

  2. Du må skrive en egendefinert funksjon for hver type som type er A eller type er B, som igjen ville føre til massiv overhead i min kontekst.

Hva er den riktige måten å nærme seg dette på i TypeScript?

Svar #1

I utgangspunktet er det bare 2 alternativer som beskrevet i det aksepterte svaret på dette spørsmålet.

Det du kan gjøre er å sjekke at formen på et objekt er det du forventer, og TypeScript kan fastslå typen ved kompileringstid ved å bruke en brukerdefinert typevern som returnerer sann (annotert returtype er et "type-predikat" av formen arg is T) hvis formen samsvarer med forventningen din:

For klasse-typer kan du bruke JavaScripts instanceof for å bestemme hvilken klasse en instans kommer fra, og TypeScript vil automatisk snevre inn typen i typekontrolløren.

En sidesetning fra meg:

Hvis du har samme propertynavn, kan du potensielt refaktorere koden din ved å bruke generics, som:

interface A {
    value: string
}

interface B {
    value: number
}

interface C {
    value: SomeCustomInterface
}

interface D {
    value: OtherCustomInterface
}

kan være

interface GenericInterface<T>{
 value: T
}

Relaterte artikler