我经常使用
之类的代码<meta name="viewport" content="width=device-width, initial-scale=1.0">
这样,我既可以使用export type Stuff = 'something' | 'else'
export const AVAILABLE_STUFF: Stuff[] = ['something', 'else']
类型,也可以在需要时遍历所有可用的东西。
这有效,但是感觉像重复两次信息。而且,您必须小心,因为Stuff
或Stuff
的更新也需要更新其对应的内容。
是否有更好的方法可以从Array定义类型,或者甚至可以使用该数组来键入某些数据?
答案 0 :(得分:4)
你可以这样做-
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[]