TypeScript数组到字符串文字类型

Dun*_*Luk 26 arrays string types typescript

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

const furniture = ['chair', 'table', 'lamp'];
type Furniture = 'chair' | 'table' | 'lamp';
Run Code Online (Sandbox Code Playgroud)

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

我基本上想说些什么type Furniture = [any string in furniture array],所以没有重复的字符串.

ggr*_*nig 53

TypeScript 3.0更新:

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

它是这样的:

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

更多关于通用休息参数

TypeScript 3.4更新(2019年3月):

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

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

const furniture = <const> ['chair', 'table', 'lamp'];
type Furniture = typeof furniture[number];
Run Code Online (Sandbox Code Playgroud)

关于新的const上下文的更多信息可以在这个PR中找到.该功能已合并为主功能,应该可用string[].

目标日期的来源

  • 使用“[number]”的原因是,如果没有它,“typeof Furniture”将返回数组类型。使用索引签名“typeof Furniture[number]”表示“家具中任何有效数字索引的类型,因此您得到的类型是值的联合,而不是数组类型。 (14认同)
  • 我可以问一下,索引签名注释“ [number]”的目的是什么?是不是可以推断? (3认同)
  • 不幸的是,这只适用于文字数组。这是行不通的: `const a = ["a", "b", "c"]; const b = a as const;` - 这将引发以下错误:`'const' 断言只能应用于对枚举成员、字符串、数字、布尔值、数组或对象文字的引用。` (2认同)

Den*_*nis 9

最好的解决方法:

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

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

const furniture = ['chair', 'table', 'lamp'];
type Furniture = typeof furniture[number];
Run Code Online (Sandbox Code Playgroud)

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

我们可以使用手动注释强制打字作为文字,但它会带来重复:

const furniture = ["chair", "table", "lamp"] as ["chair", "table", "lamp"];
type Furniture = typeof furniture[number];
Run Code Online (Sandbox Code Playgroud)

TypeScript 问题#10195跟踪提示TypeScript的能力,该列表应该被推断为静态元组而不是string[],因此将来可能会这样.


bri*_*web 9

在 TypeScript 3.4 中最简单:(注意 TypeScript 3.4 添加了const 断言

const furniture = ["chair", "table", "lamp"] as const;
type Furniture = typeof furniture[number]; // "chair" | "table" | "lamp"
Run Code Online (Sandbox Code Playgroud)

另请参阅/sf/answers/3885388951/

或者,如果您将这些作为对象中的键,您也可以将其转换为联合:

const furniture = {chair:{}, table:{}, lamp:{}} as const;
type Furniture = keyof typeof furniture; // "chair" | "table" | "lamp"
Run Code Online (Sandbox Code Playgroud)