打字稿从元组/数组值派生联合类型 [英] Typescript derive union type from tuple/array values

查看:33
本文介绍了打字稿从元组/数组值派生联合类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有清单const list = ['a', 'b', 'c']

是否可以从 'a' 的值联合类型派生?'b' |'c'?

我想要这个是因为我想定义只允许来自静态数组的值的类型,并且还需要在运行时枚举这些值,所以我使用数组.

I want this because I want to define type which allows only values from static array, and also need to enumerate these values at runtime, so I use array.

示例如何使用索引对象实现:

Example how it can be implemented with an indexed object:

const indexed = {a: null, b: null, c: null}
const list = Object.keys(index)
type NeededUnionType = keyof typeof indexed

我想知道是否可以在不使用索引地图的情况下做到这一点.

I wonder if it is possible to do it without using an indexed map.

推荐答案

2019 年 2 月更新

TypeScript 3.4 中,应于 2019 年 3 月发布 可以告诉编译器将文字元组的类型推断为文字元组,而不是例如 string[],通过使用as const 语法.这种类型的断言会导致编译器为值推断出可能的最窄类型,包括将所有内容设为 readonly.它应该是这样的:

UPDATE Feb 2019

In TypeScript 3.4, which should be released in March 2019 it will be possible to tell the compiler to infer the type of a tuple of literals as a tuple of literals, instead of as, say, string[], by using the as const syntax. This type of assertion causes the compiler to infer the narrowest type possible for a value, including making everything readonly. It should look like this:

const list = ['a', 'b', 'c'] as const; // TS3.4 syntax
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';

这将消除对任何类型的辅助函数的需求.再次祝大家好运!

This will obviate the need for a helper function of any kind. Good luck again to all!

看起来,从 TypeScript 3.0 开始,TypeScript 可以自动推断元组类型.一旦被释放,你需要的tuple()函数可以简洁地写成:

It looks like, starting with TypeScript 3.0, it will be possible for TypeScript to automatically infer tuple types. Once is released, the tuple() function you need can be succinctly written as:

export type Lit = string | number | boolean | undefined | null | void | {};
export const tuple = <T extends Lit[]>(...args: T) => args;

然后你可以像这样使用它:

And then you can use it like this:

const list = tuple('a','b','c');  // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'

希望对人们有用!

自从我发布这个答案后,如果您愿意向库中添加函数,我找到了一种推断元组类型的方法.查看 tuple.ts 中的函数 tuple().使用它,您可以编写以下内容而不再重复自己:

Since I posted this answer, I found a way to infer tuple types if you're willing to add a function to your library. Check out the function tuple() in tuple.ts. Using it, you are able to write the following and not repeat yourself:

const list = tuple('a','b','c');  // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'

祝你好运!

一个问题是文字 ['a','b','c'] 会被推断为类型 string[],所以类型系统会忘记关于具体数值.您可以强制类型系统将每个值作为文字字符串记住:

One problem is the literal ['a','b','c'] will be inferred as type string[], so the type system will forget about the specific values. You can force the type system to remember each value as a literal string:

const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[]

或者,也许更好,将列表解释为元组类型:

Or, maybe better, interpret the list as a tuple type:

const list: ['a','b','c'] = ['a','b','c']; // tuple

这是烦人的重复,但至少它不会在运行时引入无关对象.

This is annoying repetition, but at least it doesn't introduce an extraneous object at runtime.

现在你可以像这样得到你的工会:

Now you can get your union like this:

type NeededUnionType = typeof list[number];  // 'a'|'b'|'c'.

希望有所帮助.

这篇关于打字稿从元组/数组值派生联合类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆