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

问题描述 投票:3回答:2

我经常使用代码如

export type Stuff = 'something' | 'else'
export const AVAILABLE_STUFF: Stuff[] = ['something', 'else']

这样我就可以使用Stuff类型,并在需要时迭代所有可用的东西。

这有效,但感觉就像重复两次信息。而你必须要小心,因为更新StuffAVAILABLE_STUFF也需要更新其对应物。

有没有更好的方法从Array定义类型,甚至有点使用数组键入一些数据?

typescript typescript-typings
2个回答
2
投票

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

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

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

另一种选择是从AVAILABLE_STUFF的类型中提取类型。为此,我们必须强制编译器为AVAILABLE_STUFF推断字符串文字的元组。这可以使用3.4as 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
投票

另一种可能性是创建一个对象并使用keyof。我推荐这种方式只有你有任何有用的东西存储为值(在下面的代码中代替null)。

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

type Stuff = keyof typeof stuffDict
const AVAILABLE_STUFF = Object.keys(stuffDict) as Stuff[]
© www.soinside.com 2019 - 2024. All rights reserved.