Wzorce
Jak przyjąć `href` albo `onClick`, ale odrzucić obiekty podające oba?
Połącz dwa kształty unią i dodaj unikalne klucze drugiej strony jako opcjonalne właściwości `never`.
Przepis
type Without<T, U> = { [K in Exclude<keyof T, keyof U>]?: never } type XOR<T, U> = | (T & Without<U, T>) | (U & Without<T, U>) type LinkProps = XOR< { href: string }, { onClick: () => void } >
Build to kompiluje i sprawdza każdy wynik poniżej.
Jak to działa
- 01
[K in Exclude<keyof T, keyof U>]?: never
Unikalne klucze przeciwnej gałęzi mogą być nieobecne, ale nigdy nie mogą zawierać wartości.
- 02
| (U & Without<T, U>)
Każdy składnik unii łączy wymagany kształt z zakazem drugiego.
Co dostajesz
{ href: string } extends LinkProps ? true : false→true{ onClick: () => void } extends LinkProps ? true : false→true{ href: string; onClick: () => void } extends LinkProps ? true : false→false
Gdzie to zawodzi
To jest najczytelniejsze dla dwóch małych kształtów. Duże nakładające się typy dają hałaśliwe komunikaty, a `exactOptionalPropertyTypes` zmienia, czy jawne `undefined` spełnia opcjonalne `never`.
Wniosek
Użyj opcjonalnego `never`, by powiedzieć, że właściwość należy do drugiej gałęzi i nie może się tu pojawić.
