Home > Software engineering >  typescript uses generics to reorganize read-only array types
typescript uses generics to reorganize read-only array types

Time:11-18

I tried to restructure the type of the read-only array, but it didn't work:

const store: Record<string, any> = {
  aaa: '123',
  bbb: null,
  ccc: []
}

const getValues = <Keys extends readonly string[]>(keys: Keys): ReadonlyArray<[Keys[number], unknown]> => {
  return keys.map((key) => ([key, key in store ? store[key] : null]))
}

const keyArr = ['aaa', 'bbb'] as const
getValues(keyArr)  // current getValues function types:  const getValues: <readonly ["aaa", "bbb"]>(keys: readonly ["aaa", "bbb"]) => readonly ["aaa" | "bbb", unknown][]

// I want:  const getValues: <readonly ["aaa", "bbb"]>(keys: readonly ["aaa", "bbb"]) => readonly [["aaa", unknown], ["bbb", unknown]]

Here is the typescript Playground code link.

CodePudding user response:

You can map over the tuple using a mapped type. Mapping over a tuple type using a mapped type also produces a tuple as a result since TypeScript 3.1.

const getValues = <Keys extends readonly string[]>(keys: Keys) => {
  return keys.map((key) => (
    [key, key in store ? store[key] : null])
  ) as { [K in keyof Keys]: [Keys[K], unknown] }
}

TypeScript is not able to correctly understand that the type of the resulting array matches the return type. So a type assertion is needed.


Playground

  • Related