Typescript中如何访问可能为空的对象的属性?
问题原因
Typescript 静态校验要求,从联合类型对象上解构属性时,该属性必须存在于联合类型的所有分支中。你代码中sampleObj的类型是ISample | {},空对象分支{}没有声明requiredProp、optionalProp两个属性,因此触发报错,哪怕你设置了解构默认值也无法跳过该校验。
可行解决方案(均不需要使用any类型)
方案1:调整联合类型定义(最推荐)
你想要的「支持空对象、也支持符合ISample结构的对象」的语义,完全可以用Partial<ISample>实现,该工具类型会把ISample的所有属性转为可选,天然允许空对象:
interface ISample { requiredProp: string optionalProp?: string } // Partial<ISample> 等价于 { requiredProp?: string; optionalProp?: string },允许赋值为空对象 const sampleObj: Partial<ISample> = { requiredProp: "hello" } const { requiredProp = "default", optionalProp = "default" } = sampleObj console.log(requiredProp, optionalProp) // 正常运行,无类型报错
方案2:解构时加类型断言
如果你必须保留ISample | {}的联合类型定义,可以在解构时将对象断言为ISample类型。运行时空对象解构不存在的属性会得到undefined,正好触发你设置的默认值,因此该断言是安全的:
interface ISample { requiredProp: string optionalProp?: string } const sampleObj: ISample | {} = { requiredProp: "hello" } // 解构时加类型断言 const { requiredProp = "default", optionalProp = "default" } = sampleObj as ISample console.log(requiredProp, optionalProp) // 无报错,运行结果符合预期
方案3:先做类型收窄再解构
如果不想用类型断言,可以通过in操作符先判断属性是否存在,完成类型收窄后再处理:
interface ISample { requiredProp: string optionalProp?: string } const sampleObj: ISample | {} = { requiredProp: "hello" } let requiredProp = "default" let optionalProp = "default" // 类型收窄:判断属性存在时走ISample分支的逻辑 if ('requiredProp' in sampleObj) { requiredProp = sampleObj.requiredProp optionalProp = sampleObj.optionalProp ?? "default" } console.log(requiredProp, optionalProp) // 无报错,运行结果符合预期
内容的提问来源于stack exchange,提问作者DaDo
相关产品推荐
相关产品推荐

