javascript 确保数组具有联合中的所有类型

rqcrx0a6  于 2023-01-29  发布在  Java
关注(0)|答案(2)|浏览(124)

假设我有一个像这样的工会

type Colors = 'red' | 'blue' | 'pink'

有没有可能根据这个并集对数组进行类型检查,并确保数组包含所有类型?
即:

const colors: UnionToTuple<Colors> = ['red', 'blue']  // type error, missing 'pink'
const colors: UnionToTuple<Colors> = ['red', 'blue', 'pink']  // no error
5hcedyr0

5hcedyr01#

借鉴this答案的思路,您可以创建一个函数,通过使用所传递数组的类型参数T进行类型检查。将其键入为T extends Colors[]以确保数组的每一项都在Colors中,还将其键入为[Colors] extends [T[number]] ? unknown : 'Invalid'以确保Colors类型的每一项都在所传递数组中:

type Colors = 'red' | 'blue' | 'pink';
const arrayOfAllColors = <T extends Colors[]>(
  array: T & ([Colors] extends [T[number]] ? unknown : 'Invalid')
) => array;

const missingColors = arrayOfAllColors(['red', 'blue']); // error
const goodColors = arrayOfAllColors(['red', 'blue', 'pink']); // compiles
const extraColors = arrayOfAllColors(['red', 'blue', 'pink', 'bad']); // error

更一般地说,将它 Package 在另一个函数中,以便可以传递和使用联合类型的类型参数:

type Colors = 'red' | 'blue' | 'pink';
const arrayOfAll = <T>() => <U extends T[]>(
  array: U & ([T] extends [U[number]] ? unknown : 'Invalid')
) => array;
const arrayOfAllColors = arrayOfAll<Colors>();

const missingColors = arrayOfAllColors(['red', 'blue']); // error
const goodColors = arrayOfAllColors(['red', 'blue', 'pink']); // compiles
const extraColors = arrayOfAllColors(['red', 'blue', 'pink', 'bad']); // error
wgx48brx

wgx48brx2#

扩展确定性性能的答案,对于广义函数,您可以编写工厂

type Colors = 'red' | 'blue' | 'pink';

const enforceArrayMembers =
    <T>() =>
    <U extends T[]>(
        array: U & ([T] extends [U[number]] ? unknown : 'Invalid'),
    ) =>
        array;

const arrayOfAllColors = enforceArrayMembers<Colors>();
const missingColors = arrayOfAllColors(['red', 'blue']); // error
const goodColors = arrayOfAllColors(['red', 'blue', 'pink']); // compiles
const extraColors = arrayOfAllColors(['red', 'blue', 'pink', 'bad']); // error

// as IFEE
const missingColors2 = enforceArrayMembers<Colors>()(['red', 'blue']); // error
const goodColors2 = enforceArrayMembers<Colors>()(['red', 'blue', 'pink']); // compiles
const extraColors2 = enforceArrayMembers<Colors>()(['red', 'blue', 'pink', 'bad']); // error

相关问题