T[keyof T] 是否像分配条件类型一样工作?

aza*_*uha 5 typescript typescript-generics

我试图从分布式条件类型部分理解这个例子:

条件类型与映射类型结合使用时特别有用:

type FunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我不清楚索引访问运算符的用法。这是使用相同想法的最简单示例(据我所知):

type Foo = {
    prop1: never;
    prop2: never
    method1: "method1";
    method2: "method2";
}

type FunctionPropertyNames = Foo[keyof Foo] // "method1" | "method2"
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:索引访问运算符的这种用法只是分布式条件类型的一种特殊情况吗?因为它看起来像结果类型是 T[K] 的所有应用程序的联合,never因为是空联合”而被过滤never


更新。我将尝试更准确地表述这个问题:TS 手册描述了映射类型和条件类型的语法是什么。但是,我没有找到这种类型定义形式的任何描述:

type Keys = 'name1' | 'name2' | 'name3'
type Foo = Bar[Keys]
Run Code Online (Sandbox Code Playgroud)

或者,更现实的:

type Foo = Bar[keyof Bar]
Run Code Online (Sandbox Code Playgroud)

它看起来像是某种映射,但它也提供过滤功能,如果 Keys 包含never. 所以我的问题更多是关于 TS 类型系统的这个特性是否有任何精确的描述。

Bab*_*boo 1

这是一种特定的用法,在根据属性的类型过滤对象/类的属性时非常强大。本文很好地解释了如何根据类实现或未实现的方法方便地过滤类的联合(请参阅本文的部分Refining unions with distributive conditional types

其他用途

正如您所说,使用索引访问运算符的优点有助于从联合中删除不相关的类型,但它还有其他优点,例如根据某些条件更改类型。

这是一个例子:

type SchemaType<T> = {
  [k in keyof T]: T[k] extends
    | string
    | number
    | boolean
    | Types.ObjectId
    | Client
    | Doer
    | Mission
    | Date
    | Array<any>
    ? SchemaDefinition['']
    : SchemaType<T[k]>;
};
Run Code Online (Sandbox Code Playgroud)

这是type我用来输入猫鼬文档的。

我有一个打字稿interface,它定义了 aUser是什么,并且 adocument描述了 mongoDb 中的文档。

我想要的是让实现documentinterface.

例如,如果User具有以下结构:

interface User {
  id: Types.ObjectId;
  profile: {
    first_name: string;
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望document强制执行相同的操作并且类型安全:

const schema: SchemaType<User> = {
  id: { type: Types.ObjectId },
  profile: {
    first_name: { type: String, default: '' },
  },
};
Run Code Online (Sandbox Code Playgroud)

这就是SchemaType索引访问运算符的作用。如果该属性被视为叶类型(如id和are),则必须在文档中将first_name其键入为 a 。SchemaDefinition如果它是一个对象,那么它必须按原样键入interface(就是这样SchemaType<T[k]>做的)。