Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

24. LookUp #33

Open
astak16 opened this issue Jun 26, 2022 · 0 comments
Open

24. LookUp #33

astak16 opened this issue Jun 26, 2022 · 0 comments
Labels

Comments

@astak16
Copy link
Owner

astak16 commented Jun 26, 2022

题目

题目链接:LookUp

实现 LookUp,满足下面功能

import type { Equal, Expect } from '@type-challenges/utils'

interface Cat {
  type: 'cat'
  breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}

interface Dog {
  type: 'dog'
  breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
  color: 'brown' | 'white' | 'black'
}

type Animal = Cat | Dog

type cases = [
  Expect<Equal<LookUp<Animal, 'dog'>, Dog>>,
  Expect<Equal<LookUp<Animal, 'cat'>, Cat>>,
]

答案

方法一

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

T extends { type: U } 会利用分配率

  • Dog extends { type: "dog" } => true => Dog
  • Cat extends { type: "cat" } => false => never

得到 Dog | never 的联合类型,由于 never 是所有类型的子类型,所以最后得到 Dog

方法二

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

简化了方法一,不需要通过对象取值

方法三

type LookUp<T, U extends string> = T extends (U extends T[keyof T] ? T : never)
  ? T
  : never;

方法二中 { type: U },可以写成 U extends T[keyof T] ? T : never

方法四

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

这里 T["type"] extends U 不会运用分配率,会一直输入 never

为了能够让分配率生效,需要一个前置条件 T extends unknown

@astak16 astak16 added the medium label Jun 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant