JUNNNN
JUNNNN

Reputation: 63

Trying to assign multiple keyof to a dynamic desctured object in Typescript

Here's a working example to illustrate my question.


interface Definition {
  oneTitle: string
  oneDescription: string
  twoTitle: string
  twoDescription: string
}

const obj = {
  oneTitle: 'Title 1',
  oneDescription: 'Desc 1',
  twoTitle: 'Title 2',
  twoDescription: 'Desc 2'
}

type Keys = 'one' | 'two'

const keys: Keys[] = [
  'one',
  'two'
]

keys.forEach((key) => {
  const {
    [`${key}Title` as keyof Definition]: title,
    [`${key}Description` as keyof Definition]: description,
  } = obj
})

As you can see, there's a dynamic object descturation, eg. [`${key}Title`]. I'd like to know if there is in that case a way in Typescript to avoid to define multipe times as keyof Definition for every key?

I've tried the following things without any success.

const {
  [`${key}Title`]: title,
  [`${key}Description`]: description,
}: Record<keyof Definition, Definition> = config
const {
  [`${key}Title`]: title,
  [`${key}Description`]: description,
}: {[key in keyof Definition]: Definition} = config

Indeed, as I'm getting that error in both cases has no matching index signature for type 'string, it's seems that Typescript is interpreting the dynamic key as a string rather than a keyof of the Definition type.

Thanks for your help (:

Upvotes: 3

Views: 190

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370779

It's not a huge improvement, but if you prevent automatic type widening in 2 places, you can remove the need for as keyof Definition, though the code will still be a bit repetitive. Declare the keys array as const so it doesn't get widened to string[], and declare the property accessor as const so it also doesn't get widened to string.

const keys = [
  'one',
  'two'
] as const;

keys.forEach((key) => {
  const {
    [`${key}Title` as const]: title,
    [`${key}Description` as const]: description,
  } = obj
})

Upvotes: 1

Related Questions