使用对象的键作为联合类型

Posted

技术标签:

【中文标题】使用对象的键作为联合类型【英文标题】:Use keys of an object as union-type 【发布时间】:2020-04-02 17:34:54 【问题描述】:

我有一个对象(让它被冻结以便打字稿可以更好地处理它的键):

const obj = Object.freeze(
    'hello': 64,
    'world': 20
) as [key: string]: number;

现在我有一个功能,用户可以通过按键选择值:

const pick = (keys: Array<string>): Array<number> => 
    const values = [];

    for (const key of keys) 

        // Check if object contains property-key
        if (!(key in obj)) 
            throw new Error(`There's no such key: $key`);
        

        values.push(obj[key]);
    

    return values;
;

到目前为止,这看起来不错,并且在我检查用户是否传递了任何无效密钥的运行时完美运行。但是如何告诉 TS 只能使用来自obj 的键呢?

我可以使用Array&lt;'hello' | 'world'&gt;,但我需要在向obj 添加新属性时对其进行更新,这有点烦人。

相关问题,但它们似乎都使用类型,而我只有一个对象(如果有帮助,可以冻结):

    Make union type of objects from type keys(他有类型,我有对象) get union type of object keys filtered by type of object value(与 1 基本相同,但他想要 type 而我正在尝试构建一个类型 我的对象) Get keys of union of objects in TypeScript(看起来不错,但他也有类型……)

【问题讨论】:

【参考方案1】:
const obj = Object.freeze(
    'hello': 64,
    'world': 20
);

const pick = (keys: Array<keyof typeof obj>) ...

如您所见,我已删除 as [key: string]: number;,因为它扩大了类型,您希望在此严格。

接下来是Array&lt;keyof typeof obj&gt; 我在这里声明我只接受obj 类型的键数组作为参数。

Array&lt;keyof typeof obj&gt; 动态评估为 ("hello" | "world")[],幸运的是,正如您所愿,它将反映原始 obj 中的每一个变化

【讨论】:

以上是关于使用对象的键作为联合类型的主要内容,如果未能解决你的问题,请参考以下文章

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

Typescript:环境变量的类型 Guard 作为 JSON 对象的键

当 A 和 O 都是对象的属性时,使用字符串数组 A 的值作为对象 O 中的键

mysql中的键和索引

使用字段别名作为 javascript 对象的键

map 中的键值都可以是啥类型的啊