使用 keyof 提取仅具有特定类型值的键的字符串文字联合

Posted

技术标签:

【中文标题】使用 keyof 提取仅具有特定类型值的键的字符串文字联合【英文标题】:Use keyof to extract a string literal union of only keys that have values of a specific type [duplicate] 【发布时间】:2020-09-22 21:21:07 【问题描述】:

例如,我们如何仅提取具有字符串类型的键? Here is what I have tried:

type StringEntriesOnly<T> = 
    [K in keyof T]: T[K] extends string ? T[K] : never;


type SomeType = 
    aString: string;
    aNumber: number;


const v1: StringEntriesOnly<SomeType> = 
    aString: 'Hello',
    aNumber: 10, // This is a compiler error. Good. 


type StringKeys = keyof StringEntriesOnly<SomeType>;

const v2: StringKeys = 'aNumber'; // How can we make the compiler complain here?

在上面的例子中,我希望StringKeys 只允许'aString'。

【问题讨论】:

确实是重复的。 【参考方案1】:

我通常这样定义KeysMatching

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

-? 避免了一些带有可选属性的陷阱,同时引入了其他陷阱;检查边缘情况)

这给了你

type StringKeys = KeysMatching<SomeType, string>;
// type StringKeys = "aString"

const v2: StringKeys = 'aNumber'; // error!

希望对您有所帮助。 Playground link

【讨论】:

为什么要打扰-?KeysMatching 没有那个就可以工作。 如果你的SomeType 有可选的属性,没有它你会觉得奇怪。尝试将aNumber 设为可选,看看会发生什么。 undefined 渗入答案。 点赞this

以上是关于使用 keyof 提取仅具有特定类型值的键的字符串文字联合的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 中是不是有一种编译时方法来声明一个 keyof 类型,只有映射到特定类型的键? [复制]

在打字稿映射类型中过滤 keyof 意外工作

如何在字典中提取特定值(仅包含其键的值)

具有未知键的对象的打字稿类型,但只有数值?

ValueError:列的长度必须与具有多个输出的键的长度相同

打字稿 |从对象 T 中提取具有类型 K 值的所有键名