Typescript 泛型 T extends T?

起因是在做一道 typescript 类型题目:

有时,您可能希望根据某个属性在联合类型中查找类型。

在此挑战中,我们想通过在联合类型 Cat | Dog 中搜索公共 type 字段来获取相应的类型。换句话说,在以下示例中,我们期望 LookUp<Dog | Cat, 'dog'> 获得 DogLookUp<Dog | Cat, 'cat'> 获得 Cat

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

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

type MyDog = LookUp<Cat | Dog, 'dog'> // expected to be `Dog`

答题区,有兴趣可以先自行思考下:

/* _____________ 你的代码 _____________ */

type LookUp<U, T> = any


/* _____________ 测试用例 _____________ */
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>>,
]

然后看到其中一个答案:

// T extends T
// 从而提取联合类型中的各个子类
type LookUp<T extends { type: string;[key: string]: any }, U extends T["type"]> = T extends T
  ? U extends T["type"]
  ? T
  : never
  : never;

于是问题来了,这里的 T extends T 我不理解,能否详细讲讲呢?

阅读 2k
1 个回答

好问题,我重新学习了extends。感谢题主。
原文链接在这里:TypeScript 的 extends 条件类型

extends判断联合类型时:

type A = 'x'
type B = 'x' | 'y'
type Y = A extends B ? true : false; // true

注意:联合类型 A 的所有子类型,在联合类型 B 中存在,则条件满足。

当联合类型无法判断时:
什么时候无法判断呢?

type AB<T> = T extends 'x' ? 'a' : 'b';
/** 
* 由于需要判断T中的所有子类型,都符合'x',
* TypeScript 也不知道答案是true还是false,可以认为此处进行了两次判断。
* 于是乎它就把两个结果的值都返回给我们了
*/
type All = AB<'x' | 'y'>; 
// 得到 type All = 'a' | 'b';

所以问题中的判断过程可以理解为:

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

    //Cat在T中存在吗? 存在则:'dog' 在 Cat['type']中吗 ? 存在则:Cat
    //Dog在T中存在吗? 存在则:'dog' 在 Dog['type']中吗 ? 存在则:Dog

所以 T extends T 的作用,就是让TypeScript去判断 T的所有子类型 是否都在T中存在,这个过程中做到了 分离联合类型

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏