¿Cómo creo un tipo para un arreglo de valores de enumeración con miembros obligatorios en TypeScript?
¿Cómo creo type/interface (AnyColorsWithBlackAndWhite en el ejemplo a continuación) para un array de valores de enum con miembros obligatorios? Necesito que black Y white siempre estén presentes. Intenté intersectar, omitir y extender tanto Array<Color> como Array<Color.black | Color.white> al mismo tiempo, pero hasta ahora no tuve suerte:
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];Respuesta #1
Veo dos maneras, o creas una función para inferencia y validación o creas una unión de todos los estados permitidos. Primer enfoque:
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
ingresa la descripción del enlace aquí
Segundo :
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
Parque infantil
Como habrás notado, he creado todos los posibles estados de este arreglo. Es mucho: 6!=6 * 5 * 4 * 3 * 2 * 1
TupleUnion genera una combinación de todos los estados permitidos y hace que cada color que no sea blanco o negro sea opcional
