【问题标题】:get `keyof` non-optional property names in typescript在打字稿中获取“keyof”非可选属性名称
【发布时间】:2018-06-13 05:44:59
【问题描述】:

这是我的界面

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

但我只想要非可选键,也就是。 "key" | "value",或者只是"key"(两者都适合我)

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

type NonOptionalX = {
    [P in keyof X]-?: X[P]
}

type NonOptionalKeyOfX = keyof NonOptionalX 给出"key" | "value" | "default",因为-? 仅删除可选修饰符并使它们全部变为非可选。

ps。我使用打字稿 2.9。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以使用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'
    

    此评论也可能是相关的:https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458

    【讨论】:

      【解决方案2】:

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

      虽然涵盖了更简单的"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]
      

      它是如何工作的:

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

      更新:readonly 更棘手。阅读herehere。你可以将一个对象完全拆解成一个元组like this

      【讨论】:

      • 这种过滤器的唯一缺点是在使用keyof T 获取所有对象键时会丢失显示键字符串的编译器错误。但是错误仍然很清楚:Type '"foo"' is not assignable to type 'NonOptionalKeys&lt;Bar&gt;'
      猜你喜欢
      • 2021-11-30
      • 2023-02-10
      • 2023-02-16
      • 2022-07-27
      • 2018-06-05
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多