javascript - Hur definierar man en funktion med ett objekt med flera poster som argument, som bara accepterar en post?


Föreställ dig en funktion som tar ett objekt som argument som har två poster med vilken typ som helst.

const x = ({a,b}:{a: string, b: string}) => {
    // return something
}

x({a: "foo"}) // OK
x({b: "bar"}) // OK
x({a: "foo", b: "bar"}) // get a compile error in this case!

Hur kan vi ställa in denna funktion på ett sätt som gör att endast en av posterna kan skickas till funktionen? Med andra ord, jag behöver få ett kompilatorfel när båda posterna är inställda i funktionen. Till exempel, om "a" redan skickas, så fort "b" också skickas får vi ett kompilatorfel och vice versa.

Svar #1

Mitt ursprungliga intuitiva och uppenbart felaktiga svar: Använd en unionstyp:

{ a: string } | { b: string }

Detta kommer inte att utlösa ett kompileringsfel för x({a: "foo", b: "bar"}).

Fungerande lösning: Du kan följa detta råd för "ömsesidigt uteslutande typer" :

type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;

const x = (args: XOR<{ a: string }, { b: string }>) => {
    // return something
}

x({a: "foo"}) // OK
x({b: "bar"}) // OK
x({a: "foo", b: "bar"}) // get a compile error in this case!

Se TypeScript-lekplats