Reputation: 63
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
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