如何根据数组的值定义类型? [英] How to define a type based on values of an array?

查看:29
本文介绍了如何根据数组的值定义类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个看起来像数组的类型:

If I have a type which looks like an array:

type names = ['Mike', 'Jeff', 'Ben'];

我可以很容易地定义另一种类型,它在 names 中有项目的值:

I can easily define another type which has values of items in names:

type UserName = names[number]

对于函数:

function hello(name: UserName) {
  console.log(`Hello, ${name}!`)
}

我只能将MikeJeffBen 中的一个传递给hello 函数.如果我提供其他值,例如 John,则无法编译.

I can only pass one of Mike, Jeff, Ben to function hello. If I give other values, like John, it can't compile.

如果我没有 type names 而是 const 数组 names 怎么办?

What if I don't have a type names, but a const array names?

const names = ['Mike', 'Jeff', 'Ben'];

type UserName = ???;

function hello(name: UserName) {
  console.log(`Hello, ${name}!`)
}

hello('Mike');

是否可以定义这样的类型UserName?

Is it possible to define such a type UserName?

推荐答案

TypeScript 3.4,应该在 2019 年 3 月发布 它将可以告诉编译器推断字符串文字元组的类型作为字符串文字元组,而不是作为string[],通过使用 as const语法.它应该是这样的:

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 string literals as a tuple of string literals, instead of as string[], by using the as const syntax. It should look like this:

const names = ['Mike', 'Jeff', 'Ben'] as const; // TS3.4 syntax
type Names = typeof names; // type Names = readonly ['Mike', 'Jeff', 'Ben'] 
type UserName = Names[number]; // 'Mike' | 'Jeff' | 'Ben'

在那之前(在 TypeScript 3.0 到 3.3 中)您可以通过使用辅助函数来获得这种效果,该函数为编译器提示推断更窄的类型:

Until then (in TypeScript 3.0 through 3.3) you can get this effect by using a helper function which gives the compiler hints to infer a narrower type:

type Narrowable = string | number | boolean | undefined | null | void | {};
const tuple = <T extends Narrowable[]>(...t: T)=> t;
const names = tuple('Mike', 'Jeff', 'Ben');

type Names = typeof names; // type Names = ['Mike', 'Jeff', 'Ben'] 
type UserName = Names[number]; // 'Mike' | 'Jeff' | 'Ben'

(请注意,在这两种情况下,您都可以跳过中间的 Names 类型,如果愿意,只需定义 type UserName = (typeof names)[number])

(Note that in both cases you can skip the intermediate Names type and just define type UserName = (typeof names)[number] if you prefer)

好的,希望有帮助.祝你好运!

Okay, hope that helps. Good luck!

这篇关于如何根据数组的值定义类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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