使用对象的键作为并集类型

时间:2019-12-09 15:21:24

标签: typescript types union-types

我有一个对象(将其冻结,以便打字稿可以更好地处理其键):

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<'hello' | 'world'>,但是每当我向obj添加新属性时,都需要对其进行更新。

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

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

1 个答案:

答案 0 :(得分:2)

const obj = Object.freeze({
    'hello': 64,
    'world': 20
});

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

您可以看到,as {[key: string]: number};在扩展类型时已经删除了,您想严格限制它。

接下来的事情是Array<keyof typeof obj>,我在这里声明,我只接受obj类型的键数组作为参数。

Array<keyof typeof obj>动态评估为("hello" | "world")[],很幸运,您希望它能反映原始obj的所有变化