1

I try to create a read-only tuple type with optional elements. The list can be of any length and contain any of the three elements 'a', 'b', and 'c'. They are Literal Types, not string type.

This is my solution by now, it seems to work. This method has a disadvantage. If I have 100 different literal types, I need to add an optional symbol ? after each element, which is very cumbersome

export interface FormAttributesConfig {
    list: readonly ['a'?, 'b'?, 'c'?];
}

const attr1: FormAttributesConfig = {
    list: ['a', 'b', 'c']
}
const attr2: FormAttributesConfig = {
    list: ['a', 'b']
}
const attr3: FormAttributesConfig = {
    list: []
}

TypeScript Playground

UPDATE:

I can use Partial utility types to make all literal types in tuple optional.

export interface FormAttributesConfig {
    list: Partial<readonly ['a', 'b', 'c']>
}

I want to know if there are any disadvantages in this way or a better way?

Lin Du
  • 88,126
  • 95
  • 281
  • 483

1 Answers1

1

// credits goes to https://stackoverflow.com/questions/68252446/is-it-possible-to-generate-string-literal-combinations-with-template-literal-in#answer-68256789
type Permutations<T extends string, U extends string = T> =
    T extends any ? (T | `${T} ${Permutations<Exclude<U, T>>}`) : never;

type ToArray<T extends string, Cache extends string[] = []> =
    (T extends `${infer Head} ${infer Tail}`
        ? ToArray<Tail, [...Cache, Head]>
        : (T extends `${infer Head}`
            ? [...Cache, Head]
            : Cache
        )
    )

type Util<T extends string> = ToArray<Permutations<T>> | []


export interface FormAttributesConfig {
    list: Util<'a' | 'b' | 'c'>
}

const attr1: FormAttributesConfig = {
    list: ['a', 'b', 'c']
}

const attr2: FormAttributesConfig = {
    list: ['a', 'b']
}

const attr3: FormAttributesConfig = {
    list: [] // allowed
}

const attr4: FormAttributesConfig = {
    list: [undefined] // error
}

ToArray splits string by empty symbol, just like stirng.split(' ') does. It iterates recursively over the string and grabs first char

Permutations computes all possible permutations.

Please keep in mind, this util is not CPU friendly Playground