type-challenges icon indicating copy to clipboard operation
type-challenges copied to clipboard

62 - Type Lookup

Open fsubal opened this issue 5 years ago • 13 comments

type LookUp<U, T extends string> = {
  [K in T]: U extends { type: T } ? U : never
}[T]

fsubal avatar Sep 03 '20 14:09 fsubal

Could you please explain what {type: T} does, thank you? I don't understand any of this at all.

lednhatkhanh avatar Sep 05 '20 07:09 lednhatkhanh

Could you please explain what {type: T} does, thank you? I don't understand any of this at all.

{type: T} here is to make a match. U extends {type: T} will be evaluated distributively, say, (Dog extends {type: 'dog'} ? Dog : never) | (Cat extends {type: 'dog'} ? Cat : never). Thus only one will come back from the final union. However, the outer mapping is actually redundant, see #149 for a simpler solution.

ashi009 avatar Sep 05 '20 13:09 ashi009

@ashi009 Thank you!

lednhatkhanh avatar Sep 07 '20 08:09 lednhatkhanh

anybody can tell me why this doesn't work.

type LookUp<U extends {type: any}, T> = U['type'] extends T ? U : never

Xxxdxs avatar Dec 10 '20 05:12 Xxxdxs

Why is it not just:

type LookUp<U, T> = U extends {type: T} ? U : never;

It is simpler and still working.

turtleflyer avatar Jan 14 '21 02:01 turtleflyer

anybody can tell me why this doesn't work.

type LookUp<U extends {type: any}, T> = U['type'] extends T ? U : never

I believe it's because conditional types are only distributive when they have the form "T extends ..." (for any type parameter T); a more complex expression left of "extends" does not trigger distributivity.

One benefit of this design is that you can avoid distributivity if you need to by wrapping both sides in an array, as described in the new handbook.

It is rather subtle though; I'm curious if there is any other motivation behind this design choice.

rosejr avatar Feb 07 '21 01:02 rosejr

Why is this recommended compared to the simpler solution:

type LookUp<U, T extends string> = U extends { type: T } ? U : never

diraneyya avatar Apr 29 '23 17:04 diraneyya

anybody can tell me why this doesn't work.

type LookUp<U extends {type: any}, T> = U['type'] extends T ? U : never

May you need write as the follow to triggle distributive condition type:

type LookUp<U extends { type: string }, T> = U extends U
	? U["type"] extends T
		? U
		: never
	: never;

stevenaces avatar May 07 '23 06:05 stevenaces

[K in T] How to understand it ,could somebody tell me Why need it

manyuemeiquqi avatar Aug 03 '23 10:08 manyuemeiquqi

type LookUp<U, T extends string> = {
    [K in T]: U extends { type: K } ? U : never
}[T]

zsc347 avatar Sep 12 '23 05:09 zsc347

type LookUp<U extends {type:string,[key:string]:any}, T extends U['type']> =U extends {type:T}?U:never

soeasyjx avatar Jun 04 '24 02:06 soeasyjx

U['type']

U['type']:The string type is not a literal type

soeasyjx avatar Jun 04 '24 02:06 soeasyjx

A more universal solution that makes a lookup not only within the 'type' property:

type LookUp<U, T> = U extends infer K ? T extends K[keyof K] ? K : never : never;
  • U extends infer K -- same as 'iterate through union U; K is 'current' member'
  • T extends K[keyof K] -- does T belongs to the values of the current type? If so, return it, otherwise return 'never'

donkey-hott avatar Oct 18 '24 19:10 donkey-hott

type LookUp<U, T extends string> = U extends {type:T} ? U : never

yfliao90 avatar Sep 25 '25 07:09 yfliao90