简体   繁体   English

在 TypeScript 中,我如何使用索引类型查询运算符来仅获取类型属性的子集?

[英]In TypeScript how do I use index type query operator to get only subset of type's properties?

I have the following code:我有以下代码:

var o = { x: 5, y: 6, z: 'hi' }
type OnlyNumberProps = keyof typeof o; // 'x' | 'y' | 'z' I want it somehow to be 'x' | 'y'
var p : OnlyNumberProps = 'z' // How to get error here ?
var z : OnlyNumberProps = 'x' // And OK here ?

How can I filter the type OnlyNumberProps to contain only names of number properties of object o ?如何过滤类型OnlyNumberProps以仅包含对象o的数字属性的名称?

This is not possible to do.这是不可能的。

The closest you can get using mapped types is this:使用映射类型可以获得的最接近的是:

var o = { x: 5, y: 6, z: 'hi' }
type TypeOfO = typeof o;

type OnlyNumber = {
    [P in keyof TypeOfO]: number;
}

But then OnlyNumber will be:但是OnlyNumber将是:

type OnlyNumbers = { x: number; y: number; z: number; }

Which isn't what you're looking for.这不是你要找的。
There's no way to filter the keys.无法过滤密钥。

I think this is a possible solution:我认为这是一个可能的解决方案:

var o = { x: 5, y: 6, z: 'hi' }

type PropertyNames<T> = {
  [k in keyof T]: T[k] extends number ? k : never
} [keyof T]

type Properties<T> = Pick<T, PropertyNames<T>>;

let c1: Properties<typeof o> = {x: 1, y: 3} //ok
let c2: Properties<typeof o> = {x: 1, y: 3, z: "huhu"} //error
let c3: Properties<typeof o> = {} //error
let c4: Properties<typeof o> = {huhu: true} //error

Playground 操场

step by step explanation:一步一步的解释:

  1. typeof o resolves to {x: number, y: number, z: string} typeof o解析为{x: number, y: number, z: string}
  2. A type like像这样的类型
 type Foo<T> = {
                 [k in keyof T]:k
               }

supplied with the type argument Foo<typeof o> resolves to {x: "x", y: "y", z: "z"}提供类型参数Foo<typeof o>解析为{x: "x", y: "y", z: "z"}

  1. A type like像这样的类型
 type Foo<T> = {
                 [k in keyof T]:T[k]
               }

supplied with the type argument Foo<typeof o> resolves to {x: number, y: number, z: string}提供类型参数Foo<typeof o>解析为{x: number, y: number, z: string}

  1. We use the conditional type T[k] extends number? k: never我们使用条件类型T[k] extends number? k: never T[k] extends number? k: never . T[k] extends number? k: never If T[k] resolves to a number the conditional type resolves to the key of T as a string literal type otherwise to never.如果T[k]解析为数字,则条件类型解析为 T 的键作为字符串文字类型,否则为 never。

  2. A type like像这样的类型

 type Foo<T> = {
                 [k in keyof T]:T[k] extends number ? k : never
               }

supplied with the type argument Foo<typeof o> resolves to {x: "x", y: "y", z: never}提供类型参数Foo<typeof o>解析为{x: "x", y: "y", z: never}

  1. In the next step we want to get a union type of the values of the above type.在下一步中,我们想要获得上述类型值的联合类型。 For this we use indexed access types indexed access types为此,我们使用索引访问类型indexed access types
type PropertyNames<T> = {
  [k in keyof T]: T[k] extends number ? k : never
} [keyof T]

supplied with the type argument PropertyNames<typeof o> resolves to "x"|"y"|never which is the same as "x"|"y"提供类型参数PropertyNames<typeof o>解析为"x"|"y"|never"x"|"y"相同

  1. In the last step we use the utility type Pick to create the desired type在最后一步中,我们使用实用程序类型Pick来创建所需的类型
Pick<typeof o, "x"|"y">

resolves to {x: number, y: number}解析为{x: number, y: number}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript:如何确保泛型类型是JSON的子集? - Typescript: How do I ensure a generic type is subset of JSON? 如何在打字稿中安全地查询派生对象的属性? - How to query derived object's properties type-safely in typescript? 如何从打字稿中嵌套对象的属性中获取类型 - How to get type from nested object's properties in typescript 你如何使用 Typescript 编译器的 Typechecker 来获取声明的(别名)类型,而不是解析的类型? - How do you use the Typescript compiler's Typechecker to get the declared (alias) type, rather than the resolved type? 如何声明 typescript 类型以保证它是另一种类型的可分配子集 - How to declare typescript type to guarantee it's an assignable subset of another type 打字稿。 如何指定对象文字属性的子集类型? - Typescript. How to specify a type of a subset of object literal properties? 在 Typescript 中,如何设置对象的类型以反映类的属性列表? - In Typescript, how do I set the type of an object to reflect a list of a class's properties? 如何在Typescript中获得泛型类型的属性 - How do you get the properties of a generic type in Typescript 如何使用 TypeScript 访问 React State 属性? 类型错误时获取属性不存在 - How do I access React State properties using TypeScript? Get property does not exist on type error 如何计算 TypeScript object 类型中使用了哪些属性? - How can I calculate which properties are in use in a TypeScript object type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM