Как: generi c, который принимает типы только для чтения? - PullRequest
0 голосов
/ 04 февраля 2020

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

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]>
}

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

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, с которым ожидается обобщенный c тип списка (any[]) Это способ указать DoSomething, что он также должен принимать элемент только для чтения?

1 Ответ

1 голос
/ 05 февраля 2020

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

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

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

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

Тест с вашими типами ( Детская площадка ):

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

type KeyKinds = {
    [K in keyof Keys]: DoSomethingWith<Mutable<Keys[K]>> // compiles now
}
...