typescript - 如何声明在类型别名中声明的仅一个别名的数组

标签 typescript

如果我有一个像这样定义的 TypeScript 类型别名:

export type PlatformType = 'em' | 'ea' | 'hi';
我如何在接口(interface)中声明一个属性,以便该属性是每个 PlatformType 的一种类型的数组别名?例如,我想要这个:
export interface Constants {
  platformTypes: PlatformType[]; // how to declare a type for platformTypes?
}
所以当我有一个 Constants 的对象时类型,我需要这个:
export const constants: Constants = {
  platformTypes: ['em', 'ea', 'hi']
}
基本上,如果我有这个,我想得到一个错误:
export const constants: Constants = {
  platformTypes: ['em', 'ea'] // should error, missing 'hi'
}
或者
export const constants: Constants = {
  // this will error anyway because 'extra' doesn't belong to PlatformType alias
  platformTypes: ['em', 'ea', 'hi', 'extra']
}
或者
export const constants: Constants = {
  platformTypes: ['em', 'em', 'ea', 'hi'] // should error, duplicate 'em'
}

最佳答案

我认为您应该定义所有允许的元组的排列。
例如,如果您有三个元素的联合,您需要创建至少 6 个元组:

["em", "ea", "hi"] | ["em", "hi", "ea"] | ["ea", "em", "hi"] | ["ea", "hi", "em"] | ["hi", "em", "ea"] | ["hi", "ea", "em"]
这是因为联合是无序的数据结构。
export type PlatformType = 'em' | 'ea' | 'hi';


// credits goes to https://twitter.com/WrocTypeScript/status/1306296710407352321
type TupleUnion<U extends string, R extends any[] = []> = {
    [S in U]: Exclude<U, S> extends never ? [...R, S] : TupleUnion<Exclude<U, S>, [...R, S]>;
}[U];

export interface Constants {
  platformTypes: TupleUnion<PlatformType>; // how to declare a type for platformTypes?
}

export const constants: Constants = {
  platformTypes: ['em', 'ea', 'hi'] // ok
}

export const constants2: Constants = {
  platformTypes: ['em', 'ea'] // error
}

export const constants3: Constants = {
  platformTypes: ['em', 'ea', 'hi', 'extra'] // error
}

export const constants4: Constants = {
  platformTypes: ['em', 'em', 'ea', 'hi'] // error
}
Playground
请记住, typescript 中联合的顺序很棘手。
请查看 this questionthis问题
您可以在我的 blog 中找到更多示例

关于typescript - 如何声明在类型别名中声明的仅一个别名的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69100938/

相关文章:

typescript - Typescript接口(interface)声明中命名函数语法的区别

Angular:将参数传递给另一个组件

angular - combineLatest 与 FormControl valueChanges 事件绑定(bind)不发出

intellij-idea - 自动引用intelliJ下载的d.ts文件

reactjs - mapbox GL 上的单击处理程序不响应使用带有 typescript 的 react Hook 的更新状态

angular - Ag-grid:如何在使用 AggFunc 时更改定义列 headerName?

javascript - 点数组的插值

typescript - 继承异常和instanceof

reactjs - 无法在 createAsyncThunk 中将 getState 类型设置为 RootState

typescript - 可以使用函数类型强制执行 "no unknown properties"吗?