reactjs - TypeScript: 属性 'value' 在类型 'string | { value: string; label: string; }' 上不存在
我无法弄清楚为什么 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 时,它不会标记该错误。找不到关于这种特定情况的类似问题/解决方案。有任何建议吗?
答案#1
正如 Roberto 在他们的评论中解释的那样,问题是 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 为你推断类型的情况。如果你在使用 useState 钩子时去掉泛型
const [inputs, setInputParams] = useState({"email":{error:false, ...
当你没有指定状态类型时,TypeScript 会根据初始值来推断。因此,由于你将 country 的初始值设置为 {error:false,value:{value:"",label:""},msg:""},TypeScript 推断 inputs.country.value 的类型为
{ value: string; label: string; }
类型 InputParams 比推断类型更宽,因此你无意中扩大了类型。
