在TypeScript中如何使用可选链操作符与变量?

7

我有以下代码,想要从变量对象的值键中传递数字,我该如何使用可选链运算符的变量来解决 "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; }; }'.
    })

https://github.com/microsoft/TypeScript/issues/13254 - zerkms
.[key] 看起来像是无效的语法。考虑到您正在通过循环变量获取键,那么该变量必须存在。在 forEach 中,variable[key] 应该始终有效。 - Taplar
1
@Taplar,不是.[key],而是?.[key],这是一个新的复合运算符。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining - zerkms
有没有安全运算符? - Taplar
@Taplar 这是一个 ?.[] 操作符,可选链接加索引。 - zerkms
显示剩余2条评论
1个回答

5

这实际上不是一个可选链的问题,而是关于Object.keys工作方式的问题。 Typescript假设对象可能具有比编译时已知的更多的键,因此这里的key类型是string而不是variablekeyof类型。为了解决这个问题,您需要让TS编译器知道所有的键在编译时都是已知的,可以使用

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

在使用 Object.keys 时,您已经将 variable 视为非空变量,因此无需使用可选链。另外,当您将 key 转换为 keyof typeof variable 时,即断言它已经存在,因此您也可以在 ?.value 前删除可选链。


好的,那么你要如何处理类似 variable && Object.keys(variable).length>1 这样的代码呢?如果它是对象上的一个方法,那么它应该是 variable?.keys().length > 1,但它不是... - Max Waterman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接