来自对象数组的打字稿模板文字类型

时间:2021-02-10 10:54:49

标签: typescript

const source = [
  { group: 'first', key: 'A' },
  { group: 'first', key: 'B' },
  { group: 'second', key: 'A' }
] as const;

type DerivedGroupKeys = `${typeof source[number]['group']}.${typeof source[number]['key']}`;
//gives "first.A" | "first.B" | "second.A" | "second.B"
type HardCodedGroupKeys = 'first.A' | 'first.B' | 'second.A';
//gives "first.A" | "first.B" | "second.A"

我希望 DerivedGroupKeysHardCodedGroupKeys 相同(没有硬编码)。我快到了,但它为我提供了组和键的所有可能组合,而不仅仅是数组中定义的组合。这可能吗?

2 个答案:

答案 0 :(得分:2)

Template Literal Types 的文档说:

<块引用>

在插值位置使用联合时,类型是每个联合成员可以表示的每个可能的字符串文字的集合:

为了克服这个问题,你可以单独映射每个数组元素,而不是映射联合。

it('should wait until text has changed', () => {
    browser.waitUntil(
        () => { return $('#someText').getText() === 'I am now different'},
        {
            timeout: 5000,
            timeoutMsg: 'expected text to be different after 5s'
        }
    );
});

答案 1 :(得分:2)

这种行为是预期的,quote 手册:

<块引用>

对于模板文字中的每个插值位置,联合交叉相乘:

您想要的是可能的,但需要一些额外的步骤。如果你考虑一下,当你用 number 索引一个元组时,结果类型可以是 any 元组成员的类型(因此,联合)。你需要的是将索引类型缩小到 numeric literal:如果你用文字 N 索引一个元组,结果类型可以是元组的第 N 个成员的类型(因此,没有联合)。

首先,我们可以得到元组索引的并集:

type Indices<A> = Exclude<keyof A, keyof any[]>;

接下来,简单地从元组创建一个映射类型,“键”作为元组索引,“值”作为所需的输出。最后,只需使用元组索引对映射类型进行索引:

type DerivedGroupKeys = { [ I in Indices<typeof source> ] : `${typeof source[I]['group']}.${typeof source[I]['key']}` }[Indices<typeof source>];
相关问题