1

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.

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.