How to use optional chaining operator with variable in typescript

4.8k Views Asked by At

I have following code and I would like to pass number from value key of variable object, How can I use variable for optional chaining operator for it to solve the error Element implicitly has an any type?

    function fun(i?: number) {
        console.log(i)
    }

    const variable = { min: { value: 1, name: 'google' }, max: {value: 2, name: 'apple'} }
    const variable2 = { min: { value: 1, name: 'google' } }
    const variable3 = { max: {value: 2, name: 'apple'} }

    fun(variable?.min.value) // working => 1
    fun(variable?.max.value) // working => 2
    fun(variable2?.min.value) // working => 1
    fun(variable2?.max.value) // working => undefined
    fun(variable3?.min.value) // working => undefined
    fun(variable3?.max.value) // working => 2

    Object.keys(variable).forEach((key) => {
        fun(variable?.[key]?.value) // working but with error Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ min: { value: number; name: string; }; max: { value: number; name: string; }; }'.
    })
1

There are 1 best solutions below

1
Xetera On BEST ANSWER

This isn't actually an optional chaining problem, but a problem with how Object.keys works. Typescript assumes that an object may have more keys than is known at compile time so the type of key here is string and not keyof variable. To get around that you would have to let the TS compiler know that all the keys are known at compile time using

Object.keys(variable).forEach((key) => {
  fun(variable[key as keyof typeof variable].value) 
})

You're already treating variable as a non-null variable when you use it in Object.keys so there's no need to additionally use optional chaining on it. Additionally, when you cast key into keyof typeof variable, you're asserting that it already exists so you can remove the optional chaining before ?.value as well.