Не саме оптимізоване рішення (і не особливо корисне), але певною мірою тип для вичерпних масивів вдалося створити.
// Type to exclude a specific type from an array
type ExcludeFromArray<T extends any[], U, Acc extends any[] = []> = T extends [infer First, ...infer Rest]
? First extends U
? [...Acc, ...Rest]
: ExcludeFromArray<Rest, U, [...Acc, First]>
: T;
// Type to generate all permutations of an array
type GeneratePermutations<T extends any[], Acc extends any[] = []> = T extends [infer First, ...infer Rest]
? {
[Index in keyof T]: GeneratePermutations<ExcludeFromArray<T, T[Index]>, [...Acc, T[Index]]>;
}[number]
: Acc;
type Writable<T> = { -readonly [P in keyof T]: T[P] };
// Test data: array of numbers as const
const numberOptions = [1, 2, 3, 4] as const;
// Type representing permutations of the numberOptions array
type NumberPermutations = GeneratePermutations<Writable<typeof numberOptions>>;
// Valid permutation examples
const validPerm1: NumberPermutations = [1, 2, 3, 4]; // valid
const validPerm2: NumberPermutations = [4, 3, 2, 1]; // valid
const validPerm2: NumberPermutations = [3, 1, 4, 2]; // valid
// Invalid permutation examples
const invalidPerm1: NumberPermutations = [1, 3, 2, 4, 5]; // invalid (too many elements)
const invalidPerm2: NumberPermutations = [1, 2, 4, 2]; // invalid (duplicate elements)
const invalidPerm3: NumberPermutations = [1, 2, 3]; // invalid (too few elements)
Можливо теж не найестетичніше рішення, але все ж таки за допомогою типів, можна отримувати підказки від тайп скрипт про невідповідність значень у масиві з енамом.
enum Language { EN = 'en', ES = 'es', FR = 'fr', DE = 'de', PT = 'pt', JA = 'ja', TR = 'tr', IT = 'it', } const languageOptions = [ Language.EN, Language.FR, Language.ES, Language.DE, Language.PT, Language.JA, Language.TR, Language.EN, ] as const satisfies Record<number, Language>; type LanguageOption = (typeof languageOptions)[number]; type IsEqual = LanguageOption extends Language ? (Language extends LanguageOption ? 1 : 0) : 0; const correctArrayType: IsEqual = 1; // invalid type (duplicate elements "en")