2019 年 2 月更新
在TypeScript 3.4, which should be released in March 2019 中,可以通过使用as const syntax。这种类型的断言导致编译器推断出一个值的最窄类型,包括将所有内容设为readonly。它应该是这样的:
const list = ['a', 'b', 'c'] as const; // TS3.4 syntax
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';
这将消除对任何类型的辅助函数的需要。再次祝大家好运!
2018 年 7 月更新
看起来,从 TypeScript 3.0 开始,TypeScript 将可以使用automatically infer tuple types。一旦发布,你需要的tuple()函数可以简洁的写成:
export type Lit = string | number | boolean | undefined | null | void | {};
export const tuple = <T extends Lit[]>(...args: T) => args;
然后你可以像这样使用它:
const list = tuple('a','b','c'); // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'
希望对人们有用!
2017 年 12 月更新
自从我发布此答案后,如果您愿意将函数添加到库中,我找到了一种推断元组类型的方法。查看tuple.ts 中的函数tuple()。使用它,您可以编写以下内容而不重复自己:
const list = tuple('a','b','c'); // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'
祝你好运!
2017 年 7 月原稿
一个问题是文字['a','b','c'] 将被推断为类型string[],因此类型系统会忘记具体的值。您可以强制类型系统将每个值记住为文字字符串:
const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[]
或者,也许更好,将列表解释为元组类型:
const list: ['a','b','c'] = ['a','b','c']; // tuple
这是令人讨厌的重复,但至少它不会在运行时引入无关的对象。
现在你可以像这样得到你的工会:
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'.
希望对您有所帮助。