#How to extract string union from intersection with object

8 messages · Page 1 of 1 (latest)

wet turtle
#
type Foo = 'foo' | 'foos'

type DFoo = Foo & {
    kind: 'foo'
}

type Bar = 'bar' | 'bars'

type DBar = Bar & {
    kind: 'bar'
}

type Union = DFoo | DBar

type Choose<T extends 'foo' | 'bar'> = Omit<Extract<Union, {kind: T}>, 'kind'>

type X = Choose<'foo'> // should return 'foo' | 'foos'
pliant trench
#

Seems difficult. I though this would have the best chance of working, but it doesn't:

proven beaconBOT
#
type RemoveKind<T> = T extends infer U & { kind: any } ? U : never;
type Test = RemoveKind<"foo" & { kind: "foo"}>
//   ^? - type Test = "foo" & {
//       kind: "foo";
//   }
vernal cliff
wet turtle
#

@vernal cliff yes thank you

#

@vernal cliff Can you explain the dark magic behind infer U & { kind: K } that forces it tosplit away from intersected string?

vernal cliff
#

i'll have to admit that i don't quite know why this works and why Retsam's doesn't. one might expect that TS is doing something along the following lines: given (say) T = DFoo = Foo & { kind: 'foo' }, to infer U such that U & { kind: 'foo' } == DFoo, the natural choice is U = Foo

#

but of course U = Foo & { kind: 'foo' } is also a valid inference