Hiv*_*aga 3 typescript typescript-typings
我试图更深入地了解 Typescript 中的高级类型,其中一种类型是 NonFunctionPropertyNames,它仅提取给定对象的属性。
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];
Run Code Online (Sandbox Code Playgroud)
我可以理解大括号内的第一部分'{ [K in keyof T]: T[K] extends Function ? never : K }',我们声明一个对象并排除扩展 Function 的属性。让我困惑的是大括号后面的部分[keyof T]。这看起来像数组的定义{...}[keyof T],但实际上它返回对象。有人可以解释一下为什么只有大括号部分不足以声明类型,以及[keyof T].
您看到的是一个类型查询。如果您对对象类型进行索引,您将获得该属性的类型。例如:
type Foo = { foo: number }['foo'] // is number
Run Code Online (Sandbox Code Playgroud)
如果您使用多个属性的联合进行索引,您将获得所有属性类型的联合:
type FooBar = { foo: number, bar: string, baz: boolean }['foo' | 'bar'] // string | number
Run Code Online (Sandbox Code Playgroud)
如果使用所有键进行索引,您将获得所有属性类型的并集:
type FooBarBaz = { foo: number, bar: string, baz: boolean }['foo' | 'bar' | 'baz'] // string | number | boolean
Run Code Online (Sandbox Code Playgroud)
但要获得所有属性名称的并集,您可以使用keyof以上类型也可以写为:
type O = { foo: number, bar: string, baz: boolean }
type FooBarBaz = O[keyof O] // string | number | boolean
Run Code Online (Sandbox Code Playgroud)
该类型{ [K in keyof T]: K }计算为对象类型,其中键的类型与表示键的文字类型相同:
type O = { foo: number, bar: string, baz: boolean }
type FooBarBaz = { [K in keyof O]: K } // { foo: "foo"; bar: "bar"; baz: "baz"; }
Run Code Online (Sandbox Code Playgroud)
条件类型的作用是使其中一些键的类型与代表键的文字类型不同,而是将它们键入为never:
type O = { foo: number, bar: string, baz: () => boolean } // baz is a function now
type NonFunctionPropertyNames = { [K in keyof O]: O[K] extends Function ? never: K } // { foo: "foo"; bar: "bar"; baz: never; }
Run Code Online (Sandbox Code Playgroud)
因此新类型仍然具有原始类型的所有键,但有些键入为相应键的文字类型,有些键入为never. 我们想要的是我们刚刚构造的类型中键的所有值类型的联合,我们可以keyof O像以前一样使用(因为该类型具有与 相同的键O):
type O = { foo: number, bar: string, baz: () => boolean } // baz is a function now
type NonFunctionPropertyNames = { [K in keyof O]: O[K] extends Function ? never: K }[keyof O] // "foo" | "bar" | never = "foo" | "bar" ;
Run Code Online (Sandbox Code Playgroud)
never总是从联合中删除,因此我们最后得到的只是那些并非从未存在过的对象键的联合。
创建O一个类型参数,您就有一个可重用的类型来获取非功能键:
type NonFunctionPropertyNames<O> = { [K in keyof O]: O[K] extends Function ? never : K }[keyof O]
type Foo = { foo: number, bar: string, baz: () => boolean } // baz is a function now
type NonFUnctionKeysOfFoo = NonFunctionPropertyNames<Foo> // "foo" | "bar"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1027 次 |
| 最近记录: |