简体   繁体   English

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

[英]TypeScript: Define a union type from an array of strings

I can't be the first person coming across this, but my searches have not turned up any useful leads yet.我不可能是第一个遇到这个问题的人,但我的搜索还没有找到任何有用的线索。 Would greatly appreciate some expert TypeScript advice.非常感谢一些专家的 TypeScript 建议。

Say I have an array:说我有一个数组:

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

and I want to define an object mapping each fruit to some fun facts about it:我想定义一个对象,将每个水果映射到一些关于它的有趣事实:

interface Facts {
    color: string,
    typicalWeight: number
}

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

How do I do that [key: members of fruits] part?我该怎么做[key: members of fruits]部分?

Bonus: How do I enforce that my fruitFacts object exhaust all the keys derived from the array as well, so that it specifies facts for Apples, Oranges, and Pears in the example above.奖励:我如何强制我的fruitFacts对象也用尽从数组派生的所有键,以便它指定上面示例中的 Apples、Oranges 和 Pears 的事实。

TypeScript 3.4 added const assertions which allow for writing this as: TypeScript 3.4 添加了const断言,允许将其写为:

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

With as const TypeScript infers the type of fruits above as readonly["Apple", "Orange", "Pear"] .使用as const TypeScript 将上面的fruits类型推断为readonly["Apple", "Orange", "Pear"] Previously, it would infer it as string[] , preventing typeof fruits[number] from producing the desired union type.以前,它会将其推断为string[] ,从而防止typeof fruits[number]生成所需的联合类型。

It can be done but first you need an extra function to help infer the string literal type for the array elements.可以这样做,但首先您需要一个额外的函数来帮助推断数组元素的字符串文字类型。 By default Typescript will infer string[] for an array even if it is a constant.默认情况下,Typescript 会为数组推断string[] ,即使它是一个常量。 After we have an array of string literal types we can just use a type query to get the desired type在我们拥有字符串文字类型数组后,我们可以使用类型查询来获取所需的类型

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

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

Since 3.4 you can also use a const type assertion instead of the stringLiteralArray function:从 3.4 开始,您还可以使用 const 类型断言代替stringLiteralArray函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM