首页 > 解决方案 > 打字稿:类型“字符串”上不存在属性“值”| {值:字符串;标签:字符串;}

问题描述

我不明白为什么 Typescript 将其标记为错误:

Property 'value' does not exist on type 'string | { value: string; label: string; }'.
Property 'value' does not exist on type 'string'.
Property 'label' does not exist on type 'string | { value: string; label: string; }'.  
Property 'label' does not exist on type 'string'.

代码实现:

type KeyParams="email"|"username"|"password"|"country"
type InputParams = Record<KeyParams, {error:boolean,value:string|{value: string, label: string}, msg:string}> 

React 功能组件内部:

const [inputs, setInputParams] = useState<InputParams>({"email":{error:false,value:"",msg:""},"username":{error:false,value:"",msg:""},"password":{error:false,value:"",msg:""},"country":{error:false,value:{value:"",label:""},msg:""}})
...
<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>

当我只在 input 和 span 元素中写入值时,它不会标记该错误inputs.country.value找不到此特定情况的任何类似问题/解决方案。有什么建议么?

标签: reactjstypescript

解决方案


正如罗伯托在他们的评论中解释的那样,问题在于它inputs.country.value可能是一个对象,也可能{ value: string; label: string; }只是一个普通的string. 那是因为你如何定义你的InputParams类型:

type InputParams = Record<KeyParams, {
    error: boolean,
    value: string | {value: string, label: string}, // <-- this union right here
    msg: string
}> 

但是在您的实际组件中,inputs.country.value始终是对象。

在这种情况下,最好让 TypeScript 为您推断类型。如果您将泛型<InputParams>放在useState钩子上,您将获得准确的类型检查:

const [inputs, setInputParams] = useState({"email":{error:false, ...

当你不指定状态类型时,TypeScript 将基于初始值。country因此,由于您为to设置了初始值{error:false,value:{value:"",label:""},msg:""},TypeScript 会推断为inputs.country.valueas

{ value: string; label: string; }

该类型InputParams比推断的类型更宽,因此您无意中扩大了类型。


推荐阅读