gpt4 book ai didi

typescript - 在 TypeScript 中,如何获取值为给定类型的对象类型的键?

转载 作者:行者123 更新时间:2023-12-05 07:00:46 26 4
gpt4 key购买 nike

我一直在尝试创建一个由 T 类型的键组成的类型其值为字符串。在伪代码中它将是 keyof T where T[P] is a string .

我能想到的唯一方法是分两步:

// a mapped type that filters out properties that aren't strings via a conditional type
type StringValueKeys<T> = { [P in keyof T]: T[P] extends string ? T[P] : never };

// all keys of the above type
type Key<T> = keyof StringValueKeys<T>;

但是 TS 编译器说 Key<T>等于keyof T ,即使我通过将它们设置为 never 来过滤掉其值不是字符串的键使用条件类型。

所以它仍然允许这样,例如:

interface Thing {
id: string;
price: number;
other: { stuff: boolean };
}

const key: Key<Thing> = 'other';

当唯一允许的值为 key 时真的应该是 "id" , 不是 "id" | "price" | "other" ,因为其他两个键的值不是字符串。

Link to a code sample in the TypeScript playground

最佳答案

这可以通过 conditional types 来完成和 indexed access types ,像这样:

type KeysMatching<T, V> = {[K in keyof T]-?: T[K] extends V ? K : never}[keyof T];

然后像这样提取属性匹配 string 的键:

const key: KeysMatching<Thing, string> = 'other'; // ERROR!
// '"other"' is not assignable to type '"id"'

详细说明:

KeysMatching<Thing, string> ➡

{[K in keyof Thing]-?: Thing[K] extends string ? K : never}[keyof Thing] ➡

{
id: string extends string ? 'id' : never;
price: number extends string ? 'number' : never;
other: { stuff: boolean } extends string ? 'other' : never;
}['id'|'price'|'other'] ➡

{ id: 'id', price: never, other: never }['id' | 'price' | 'other'] ➡

'id' | never | never ➡

'id'

注意你在做什么:

type SetNonStringToNever<T> = { [P in keyof T]: T[P] extends string ? T[P] : never };

实际上只是将非字符串属性 转换为never 属性值。它没有触及按键。你的 Thing 会变成 {id: string, price: never, other: never}。并且它的键与 Thing 的键相同。它与 KeysMatching 的主要区别在于您应该选择键,而不是值(所以是 P 而不是 T[P])。

Playground link to code

关于typescript - 在 TypeScript 中,如何获取值为给定类型的对象类型的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64032788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com