I want to traverse the properties of an object and have Typescript correcly infer the type of the key, but I can't seem to achieve, and I have to cast it.
Here's an example
type Cycle = 'year' | 'month' | 'week';
type Price = {
[key in Cycle]?: number
}
const price1: Price = { year: 20, month: 40 }
for (const key in price1) {
const cycle = key as keyof typeof price1 // wanna get rid of this cast
console.log({ key, cycle }) // --> key: string, cycle: Cycle
}
Here the typescript playground if anybody wants to give it a try
I'd like to know whay Typescript can't infer it, if there's any "risk" in doing that cast, and if there's a better, more elengant, safer or correct way to do it.
Edit: taking into account the answer I got, I came to this version using a type guard function with a type predicate:
type Cycle = 'year' | 'month' | 'week';
type Price = {
[key in Cycle]?: number
}
const price1: Price = { year: 20, month: 40 }
const isCycle = (cycle: any): cycle is Cycle => typeof(cycle) === 'string' && ['year', 'month', 'week'].includes(cycle)
for (const key in price1) {
if (isCycle(key)) {
console.log({ key }) // --> inside here key is a Cycle
}
console.log({ key }) // --> and here key is a string
}
And this is the typescript playground
However I have to keep in sync the type Cycle = 'year' | 'month' | 'week' with the isCycle function, and it gets a bit verbose.
Is there a simpler way to do this in a safe way?