#How to narrow an union type

20 messages · Page 1 of 1 (latest)

dreamy lodge
#

Say I have a type

type Transaction = { kind: 'income', customer: string } | { kind: 'expense', vendor: string };

and I need to narrow it down to just the income kind or the expense kind.

type NarrowDown<Type, Key, Value> = /* ??? implementation */

type IncomeTransaction = NarrowDown<Transaction, 'kind', 'income'> // { kind: 'income', customer: string }

is this possible?

tropic summitBOT
#
Ascor8522#7606

Preview:```ts
type Transaction =
| {kind: "income"; customer: string}
| {kind: "expense"; vendor: string}

type NarrowDown<
Type,
Key extends keyof Type,
Value extends Type[Key]

= Type extends any
? Type[Key] extends Value
? Type
: never
: never

type IncomeTransaction = NarrowDown<
Transaction,
"kind",
"income"

...```

maiden cedar
#

you can easily do that using conditional types

#

the thing is, you're dealing with a union (Transaction)

#

so you need to distribute that union first

#

see the "Distributive Conditional Types" section on the same page

#

that's why there is a "weird" extends any check first

#

@dreamy lodge

prime mist
#

what

#

im so confused

#

isn't this just Extract

#

why do you need to distribute for this

maiden cedar
#

true, it's Extract

dreamy lodge
#

oh so Extract<Transaction, { kind: 'income' }>?

prime mist
#

yes

dreamy lodge
#

makes sense thaanks

prime mist
#

for future reference your union is a discriminated union, useful for other things

and as mentioned, this is extraction, not narrowing. narrowing is figuring out the type of a value

dreamy lodge
#

can I close this or will it automatically

#

!close