如何:接受只读类型的泛型?

zed*_*yas 4 typescript typescript-generics typescript-typings

给定列表上的一个动作

type DoSomethingWith<L extends any[]> = L
Run Code Online (Sandbox Code Playgroud)

我想做的事情就是这样

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]>
}
Run Code Online (Sandbox Code Playgroud)

但为了避免冗余(在可能更长的列表上)我希望能够这样写:

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[]'.
}
Run Code Online (Sandbox Code Playgroud)

错误是我尝试传递一个只读类型DoSomething,该类型期望通用列表类型(any[])它们是指定DoSomething它也应该接受只读元素的方法吗?

for*_*d04 6

readonly是的,您可以在通用约束中使用修饰符:

type DoSomethingWith<L extends readonly any[]> = L
//                             ^ add this
Run Code Online (Sandbox Code Playgroud)

或者,在缩小范围readonly后,您可以采取相反的方式并删除标志:keysas const

type Mutable<T> = T extends object ? { -readonly [K in keyof T]: Mutable<T[K]> } : T
Run Code Online (Sandbox Code Playgroud)

使用您的类型进行测试(Playground):

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

type KeyKinds = {
    [K in keyof Keys]: DoSomethingWith<Mutable<Keys[K]>> // compiles now
}
Run Code Online (Sandbox Code Playgroud)