在打字稿中获取`keyof`非可选属性名称

for*_*tyj 1 typescript

这是我的界面

interface X {
    key: string
    value: number | undefined
    default?: number
}
Run Code Online (Sandbox Code Playgroud)

但是我只想要非可选键。"key" | "value",或者"key"(对我都很好)

type KeyOfX = keyof X给我"key" | "value" | "default"

type NonOptionalX = {
    [P in keyof X]-?: X[P]
}
Run Code Online (Sandbox Code Playgroud)

type NonOptionalKeyOfX = keyof NonOptionalX给出"key" | "value" | "default"-?仅删除任意的改性剂,让所有的人都非可选。

ps。我使用Typescript 2.9。

pol*_*.ph 8

但我只想要非可选键,也就是。“钥匙” | “值”,或只是“键”(两者都适合我)

虽然"key"涵盖了更简单的选项,但我想涵盖一个不太明显的选项"key" | "value"。可能需要它,因为value它不是可选字段。它可以分配undefined,但它应该通过"value" in x检查。

type NonOptionalKeys<T> = { [K in keyof T]-?: T extends { [K1 in K]: any } ? K : never}[keyof T]
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  • 映射对象类型 ( K) 中的键实际上不仅是类型,而且是附加了“必需”和“只读”的类型;
  • Twith键的迭代-?使得在将它们放入之前需要可选键K
  • { [K1 in K]: any } object 是具有单个必需键的对象
  • 如果原始类型扩展它,则需要该键,我们将其名称保留为该键的值类型;
  • 可选键未通过检查并被收集为never;
  • 结果对象包含原始类型的键的名称作为字段以及相同的键或never值;
  • [keyof T]所有的值类型的联合被计算,never类型得到删除((A | never) = A),只有所有需要密钥的工会离开。


art*_*tem 7

您可以使用条件类型的操作形式undefined extends k ? never : k来替代never该值的键undefined能分到,然后使用一个事实,即工会T | never只是T为任何类型:

interface X {
    key: string
    value: number | undefined
    default?: number
}


type NonOptionalKeys<T> = { [k in keyof T]-?: undefined extends T[k] ? never : k }[keyof T];

type Z = NonOptionalKeys<X>; // just 'key'
Run Code Online (Sandbox Code Playgroud)

此注释也可能相关:https : //github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458