Как: универсальный, который принимает типы только для чтения?

Учитывая действие в списке

type DoSomethingWith<L extends any[]> = L

то, что я пытаюсь сделать, работает как таковое

const keys = {
  a: ['a', 'b', 'c'] as ['a', 'b', 'c'],
  d: ['d', 'e', 'f'] as ['d', 'e', 'f'],
}

type Keys = typeof keys

type KeysWithSomething = {
  [K in keyof Keys]: DoSomethingWith<Keys[K]>
}

Но чтобы избежать избыточности (в том, что может быть более длинный список), я хочу иметь возможность написать его как таковой:

const keys = {
  a: ['a', 'b', 'c'] as const,
  d: ['d', 'e', 'f'] as const,
}

type Keys = typeof keys

type DoSomethingWith<L extends any[]> = L

type KeyKinds = {
  [K in keyof Keys]: DoSomethingWith<Keys[K]>
                                  // ^^^^^^^: Type '{ a: readonly ["a", "b", "c"]; d: readonly ["d", "e", "f"]; }[K]' does not satisfy the constraint 'any[]'.
}

Ошибка заключается в том, что я пытаюсь передать тип только для чтения в DoSomething, с которым ожидается общий тип списка (any[]). Это способ указать DoSomething, что он также должен принимать элемент только для чтения?


person zedryas    schedule 04.02.2020    source источник
comment
Спасибо @ford04. Могу я спросить, как он может принимать в качестве параметров как типы только для чтения, так и не только для чтения?   -  person zedryas    schedule 04.02.2020
comment
Надо было попробовать раньше - отлично работает - можете ли вы опубликовать ответ, чтобы я мог его проверить @ford04?   -  person zedryas    schedule 04.02.2020


Ответы (1)


Да, вы можете использовать модификатор readonly в общем ограничении:

type DoSomethingWith<L extends readonly any[]> = L
//                             ^ add this

Или вы идете наоборот и удаляете флаг readonly, предварительно сузив keys с as const:

type Mutable<T> = T extends object ? { -readonly [K in keyof T]: Mutable<T[K]> } : T

Test with your types (Игровая площадка):

type T1 = Mutable<Keys> // { a: ["a", "b", "c"]; d: ["d", "e", "f"]; }

type KeyKinds = {
    [K in keyof Keys]: DoSomethingWith<Mutable<Keys[K]>> // compiles now
}
person ford04    schedule 04.02.2020