TypeScript:根据字符串数组定义联合类型

时间:2018-08-29 20:16:10

标签: typescript

我不是第一个遇到此问题的人,但我的搜索尚未找到任何有用的线索。非常感谢TypeScript专业建议。

说我有一个数组:

const fruits = ["Apple", "Orange", "Pear"];

我想定义一个对象,将每个水果映射到一些有趣的事实:

interface Facts {
    color: string,
    typicalWeight: number
}

const fruitFacts: { [key: members of fruits]: Facts } = {
    "Apple": { color: "green", typicalWeight: 150 }
    //
}

我该如何[key: members of fruits]部分?

奖金:如何强制我的fruitFacts对象也耗尽所有从数组派生的键,以便在上面的示例中为Apple,Oranges和Pears指定事实。

2 个答案:

答案 0 :(得分:13)

可以做到,但是首先您需要一个额外的函数来帮助推断数组元素的字符串文字类型。默认情况下,Typescript将为数组推断string[],即使它是常量也是如此。在拥有字符串文字类型的数组之后,我们可以仅使用类型查询来获取所需的类型

function stringLiteralArray<T extends string>(a: T[]) {
    return a;
}

const fruits = stringLiteralArray(["Apple", "Orange", "Pear"]);
type Fruits = typeof fruits[number]

从3.4开始,您还可以使用const类型断言代替stringLiteralArray函数:

const fruits = ["Apple", "Orange", "Pear"] as const;
type Fruits = typeof fruits[number]

答案 1 :(得分:7)

TypeScript 3.4添加了const assertions,允许将其编写为:

const fruits = ["Apple", "Orange", "Pear"] as const;
type Fruits = typeof fruits[number]; // "Apple" | "Orange" | "Pear"

使用as const时,TypeScript将fruits的类型推断为readonly["Apple", "Orange", "Pear"]。以前,它会将其推断为string[],从而阻止typeof fruits[number]生成所需的联合类型。