如何在typescript中为具有强制成员的枚举值数组创建类型?

9rygscc1  于 2022-11-26  发布在  TypeScript
关注(0)|答案(1)|浏览(82)

如何创建type/interface(在下面的例子中为AnyColorsWithBlackAndWhite),用于一个包含强制成员的枚举值数组?我需要blackwhite始终存在。我尝试同时交叉、省略和扩展Array<Color>Array<Color.black | Color.white>,但到目前为止没有成功:

enum Color {
  red,
  green,
  yellow,
  blue,
  black,
  white,
}

interface AnyColorsWithBlackAndWhite
  extends Array<Color | Color.black | Color.white> {}

export const Correct: AnyColorsWithBlackAndWhite = [Color.red, Color.yellow, Color.black, Color.white];

export const Wrong1: AnyColorsWithBlackAndWhite = [Color.red, Color.yellow];

export const Wrong2: AnyColorsWithBlackAndWhite = [Color.red, Color.yellow, Color.black];
lsmepo6l

lsmepo6l1#

我看到了两种方法,你要么创建一个用于推理和验证的函数,要么创建一个所有允许状态的并集。第一种方法:

enum Color {
  red,
  green,
  yellow,
  blue,
  black,
  white,
}

type RequiredElements = Color.black | Color.white

const withRequired = <
  Item extends Color,
  List extends Item[]
>(list: RequiredElements[] extends [...List] ? List : never) => list

const ok = withRequired([Color.red, Color.yellow, Color.black, Color.white]) // ok
const error = withRequired([Color.red, Color.yellow, Color.black]) // error

enter link description here
第二:

enum Color {
  red,
  green,
  yellow,
  blue,
  black,
  white,
}

// https://github.com/microsoft/TypeScript/issues/13298#issuecomment-692864087
type TupleUnion<U extends string | number, R extends any[] = []> = {
  [S in U]: Exclude<U, S> extends never
  ? S extends Color.black | Color.white
  ? [...R, S] : [...R, S?] : TupleUnion<Exclude<U, S>,
    S extends Color.black | Color.white ? [...R, S]
    : [...R, S?]
  >;
}[U];

type Ok = TupleUnion<Color>

export const Correct: Ok = [Color.red, Color.yellow, Color.black, Color.white]; // ok
export const COrrect1: Ok = [Color.red, Color.white, Color.yellow, Color.black]; // ok

export const Wrong1: Ok = [Color.red, Color.yellow]; // error

export const Wrong2: Ok = [Color.red, Color.green, Color.black]; // error

Playground
正如你可能已经注意到的,我已经创建了这个数组的所有可能状态。6!= 6 * 5 * 4 * 3 * 2 * 1
TupleUnion生成所有允许状态的组合,并使每种非白色颜色成为可选颜色

相关问题