TypeScript 数组到字符串文字类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44497388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:37:50  来源:igfitidea点击:

TypeScript array to string literal type

arraysstringtypescripttypes

提问by Duncan Luk

I currently have both an array of strings and a string literal union type containing the same strings:

我目前有一个字符串数组和一个包含相同字符串的字符串文字联合类型:

const furniture = ['chair', 'table', 'lamp'];
type Furniture = 'chair' | 'table' | 'lamp';

I need both in my application, but I am trying to keep my code DRY. So is there any way to infer one from the other?

我的应用程序中需要两者,但我试图保持我的代码干燥。那么有没有办法从另一个中推断出一个?

I basically want to say something like type Furniture = [any string in furniture array], so there are no duplicate strings.

我基本上想说类似的东西type Furniture = [any string in furniture array],所以没有重复的字符串。

回答by ggradnig

Update for TypeScript 3.0 :

TypeScript 3.0 更新:

With the use of generic rest parameters, there is a way to correctly infer string[]as a literal tuple type and then get the union type of the literals.

通过使用通用的 rest 参数,有一种方法可以正确推断string[]为文字元组类型,然后获取文字的联合类型。

It goes like this:

它是这样的:

const tuple = <T extends string[]>(...args: T) => args;
const furniture = tuple('chair', 'table', 'lamp');
type Furniture = typeof furniture[number];

More about generic rest parameters

更多关于通用休息参数

Update for TypeScript 3.4:

TypeScript 3.4 更新:

TypeScript version 3.4 has introduced so-called const contexts, which is a way to declare a tuple type as immutable and get the narrow literal type directly (without the need to call a function like shown above).

TypeScript 3.4 版引入了所谓的const contexts,这是一种将元组类型声明为不可变并直接获取窄文字类型的方法(无需调用如上所示的函数)。

With this new syntax, we get this nice concise solution:

使用这种新语法,我们得到了这个简洁的解决方案:

const furniture = ['chair', 'table', 'lamp'] as const;
type Furniture = typeof furniture[number];

More about the new const contexts is found in this PRas well as in the release notes.

在此 PR以及发行说明中可以找到有关新 const 上下文的更多信息

回答by Denis

This answer is out of date, see answer above.

此答案已过时,请参阅上面的答案。

The best available workaround:

最好的解决方法:

const furnitureObj = { chair: 1, table: 1, lamp: 1 };
type Furniture = keyof typeof furnitureObj;
const furniture = Object.keys(furnitureObj) as Furniture[];

Ideally we could do this:

理想情况下,我们可以这样做:

const furniture = ['chair', 'table', 'lamp'];
type Furniture = typeof furniture[number];

Unfortunately, today furnitureis inferred as string[], which means Furnitureis now also a string.

不幸的是,今天furniture被推断为string[],这意味着Furniture现在也是string

We can enforce the typing as a literal with a manual annotation, but it brings back the duplication:

我们可以使用手动注释将类型强制为文字,但它会带回重复:

const furniture = ["chair", "table", "lamp"] as ["chair", "table", "lamp"];
type Furniture = typeof furniture[number];

TypeScript issue #10195tracks the ability to hint to TypeScript that the list should be inferred as a static tuple and not string[], so maybe in the future this will be possible.

TypeScript问题 #10195跟踪提示 TypeScript 列表应该被推断为静态元组而不是 的能力string[],所以也许在未来这将成为可能。

回答by Fenton

The only adjustement I would suggest is to make the constguaranteed compatible with the type, like this:

我建议的唯一调整是使const保证与类型兼容,如下所示:

type Furniture = 'chair' | 'table' | 'lamp';

const furniture: Furniture[] = ['chair', 'table', 'lamp'];

This will give you a warning should you make a spelling error in the array, or add an unknown item:

如果您在数组中出现拼写错误或添加未知项目,这将向您发出警告:

// Warning: Type 'unknown' is not assignable to furniture
const furniture: Furniture[] = ['chair', 'table', 'lamp', 'unknown'];

The only case this wouldn't help you with is where the array didn't contain one of the values.

这对您没有帮助的唯一情况是数组不包含其中一个值。