TypeScript报错:类型string|{value:string;label:string}不存在value/label属性怎么解决
报错原因
你定义的InputParams中所有字段的value都是string | { value: string; label: string }联合类型,TypeScript静态检查时无法确定你访问inputs.country.value时它到底是字符串还是对象,字符串类型本身没有value和label属性,所以直接访问这两个属性就会触发类型报错。
你直接写inputs.country.value不报错是因为不管它是字符串还是对象,这个值本身是合法的,不会访问不存在的属性。
处理方案
- 方案1:优化类型定义,区分不同字段的value类型
你当前的场景里只有country的value是对象结构,其余字段都是字符串,不需要统一用Record定义,可以单独定义每个字段的类型,从根源上避免类型歧义:
type InputParams = { email: {error: boolean, value: string, msg: string} username: {error: boolean, value: string, msg: string} password: {error: boolean, value: string, msg: string} country: {error: boolean, value: {value: string, label: string}, msg: string} }
改完之后TS会默认country的value就是对象,直接访问.value和.label不会再报错。
- 方案2:使用类型收窄,访问前先判断类型
如果需要保留当前的联合类型定义,可以在访问属性前先判断value的类型:
{typeof inputs.country.value === 'object' && inputs.country.value !== null ? ( <> <input type="hidden" name="country" value={inputs.country.value.value}/> <div className="w-100 h-100 relative flex items-center"> <span className="nowrap">{inputs.country.value.label}</span> </div> </> ) : null}
- 方案3:使用类型断言,手动告知TS该值的类型
如果你100%确定country的value永远是对象结构,不会出现字符串,可以直接用类型断言跳过检查:
<input type="hidden" name="country" value={(inputs.country.value as {value: string, label: string}).value}/> <span className="nowrap">{(inputs.country.value as {value: string, label: string}).label}</span>
也可以提前提取值做断言简化代码:
const countryValue = inputs.country.value as {value: string, label: string}
内容的提问来源于stack exchange,提问作者Diego Gallo
相关产品推荐
相关产品推荐

