将 TypeScript 数组转换为字符串文本类型

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

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

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

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

63491 次浏览

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

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


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

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

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

唯一不能帮助您解决的情况是数组不包含其中一个值。

这个答案已经过时了,请参阅上面的答案。

最好的解决办法:

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

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

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

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

我们可以通过手动注释将类型作为一个文本强制执行,但它带回了重复:

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

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

TypeScript 3.4 +

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

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

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

更多关于新常量上下文的信息可以在这个 PR 释放通知书中找到。

TypeScript 3.0 +

通过使用通用静止参数,可以正确地将 string[]推断为文本元组类型,然后得到文本的联合类型。

是这样的:

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

更多关于通用静止参数的信息

最简单的打字稿3.4: (注释 TypeScript 3.4添加了 常量断言)

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

也请参阅 https://stackoverflow.com/a/55505556/4481226

或者,如果你有这些作为键在一个对象,你也可以转换为一个联合:

const furniture = {chair:{}, table:{}, lamp:{}} as const;
type Furniture = keyof typeof furniture; // "chair" | "table" | "lamp"