是否可以从数组创建打字稿类型?

时间:2019-03-06 09:57:25

标签: typescript typescript-typings

我经常使用

之类的代码
<meta name="viewport" content="width=device-width, initial-scale=1.0">

这样,我既可以使用export type Stuff = 'something' | 'else' export const AVAILABLE_STUFF: Stuff[] = ['something', 'else'] 类型,也可以在需要时遍历所有可用的东西。

这有效,但是感觉像重复两次信息。而且,您必须小心,因为StuffStuff的更新也需要更新其对应的内容。

是否有更好的方法可以从Array定义类型,或者甚至可以使用该数组来键入某些数据?

3 个答案:

答案 0 :(得分:4)

从 Typescript v3.14 开始相当简单

你可以这样做-

export const AVAILABLE_STUFF = <const> ['something', 'else'];
export type Stuff = typeof AVAILABLE_STUFF[number];

更多信息 - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions

答案 1 :(得分:2)

一个内置选项是使用枚举而不是类型和数组方法。

export enum Stuff {
    something = 'something',
    else = 'else',
}

export const AVAILABLE_STUFF: Stuff[] = Object.values(Stuff);

另一个选择是从AVAILABLE_STUFF的类型中提取类型。为此,我们必须强制编译器为AVAILABLE_STUFF推断字符串文字的元组。可以在3.4中使用as const或在3.4之前使用附加功能来完成此操作。在AVAILABLE_STUFF是元组类型之后,我们可以使用类型查询来获取元素的类型:

export const AVAILABLE_STUFF = (<T extends string[]>(...o: T)=> o)('something', 'else'); // typed as ["something", "else"]
// export const AVAILABLE_STUFF = ['something', 'else'] as const; // typed as ["something", "else"]  in 3.4
export type Stuff = typeof AVAILABLE_STUFF[number] //"something" | "else"

以上代码的一些解释。 typeof AVAILABLE_STUFF给出了常量(["something", "else"])的类型,以得到[number]称为type query,并给出了元组中项的类型。

(<T extends string[]>(...o: T)=> o)只是一个IIFE,我们用来强制编译器推断字符串文字元组类型。它必须是通用的,因为编译器只会在某些情况下推断文字类型和元组(约束为string的类型参数就是其中之一)。我建议使用as const版本,因为它更具可读性。

答案 2 :(得分:2)

另一种可能性是创建一个对象并使用keyof。仅当您有任何有用的值存储为值时才建议这样做(代替下面的代码中的null)。

const stuffDict = {
  something: null,
  else: null,
}

type Stuff = keyof typeof stuffDict
const AVAILABLE_STUFF = Object.keys(stuffDict) as Stuff[]