Typescript Conditional Types 结合映射类型文档示例说明

Posted

技术标签:

【中文标题】Typescript Conditional Types 结合映射类型文档示例说明【英文标题】:Typescript Conditional Types combined with mapped types documentation example clarification 【发布时间】:2020-01-15 06:59:10 【问题描述】:

我正在尝试了解 TypeScript 2.8 中引入的条件类型并阅读相关文档。

下面的例子可以在下面的链接中看到 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

节中有一个例子:

分布式条件类型 条件类型在与映射类型结合使用时特别有用:
type FunctionPropertyNames<T> =  [K in keyof T]: T[K] extends Function ? K : never [keyof T];

我理解了这部分 [K in keyof T]: T[K] extends Function ? K : never 它正在选择 Function 类型的所有键。但我不明白为什么最后有一个数组类型的语法 [keyof T] 它在那里做什么?为什么需要它?

提前致谢。

【问题讨论】:

【参考方案1】:

它被称为lookup type

使用数组访问语法,我们可以得到我们传入的所有属性类型的并集。

( a: string, b: number, c: object )['a' | 'b'] // -> string | number

让我们看一个例子,其中 T 是:


  a: () => void,
  b: () => void,
  c: string

FunctionPropertyNames&lt;T&gt; 的预期结果是'a' | 'b'

映射类型产生一个像这样的对象类型:


  a: 'a',
  b: 'b',
  c: never

但这不是我们想要的,我们需要属性名称作为联合类型。这就是查找类型的用武之地。

在示例中,我们使用T 的所有键,所以基本上:

( a: 'a', b: 'b', c: never )['a' | 'b' | 'c'] // -> 'a' | 'b' | never

这返回 'a' | 'b' | nevernever 无关紧要,因此 TypeScript 将其删除,我们得到 'a' | 'b'

【讨论】:

非常感谢您的详细解释以及运算符的类型(在本例中为查找),这让我有了更深入的了解。【参考方案2】:

一开始就假设sn-p只有下面

type FunctionPropertyNames<T> =  [K in keyof T]: T[K] extends Function ? K : never ;

没有数组访问器。所以基本上非函数映射到never,而函数映射到相应类型的键,即它们的函数名。

这意味着

type Foo = FunctionPropertyNames<
    bar: string;
    baz: number;
    boo(): void;
    ping(a: number): string;
>;

type Foo = 
    bar: never;
    baz: never;
    boo: "boo";
    ping: "ping";
;

都是一样的。当我们最终使用数组访问器并使用[keyof T] 访问具有T 中的键的所有类型的属性时(所以实际上在这一点上),我们得到了所有类型的联合,没有never,因为never 是总是被丢弃。

【讨论】:

非常感谢您的详细解释。

以上是关于Typescript Conditional Types 结合映射类型文档示例说明的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript教程学习笔记16篇(完结)

Typescript本地存储兼容性[重复]

TypeScript 中的 Angular 材质示例:芯片

翻译干货!开始使用 TypeScript 和 React

给 TypeScript 项目编写单元测试的一些小经验

TypeScript之Map的遍历