为何使用MUI Autocomplete示例代码会出现TypeScript错误?
MUI Autocomplete受控状态TypeScript类型错误解决
问题场景
按照MUI v5.11官网的受控状态示例实现Autocomplete组件,代码完全照搬,但在TypeScript v4.7.4环境下出现两个类型不匹配错误。
原代码
import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; const options = ['Option 1', 'Option 2']; export default function ControllableStates() { const [value, setValue] = React.useState<string | null>(options[0]); const [inputValue, setInputValue] = React.useState(''); return ( <div> <div>{`value: ${value !== null ? `'${value}'` : 'null'}`}</div> <div>{`inputValue: '${inputValue}'`}</div> <br /> <Autocomplete value={value} onChange={(event: any, newValue: string | null) => { setValue(newValue); }} inputValue={inputValue} onInputChange={(event, newInputValue) => { setInputValue(newInputValue); }} id="controllable-states-demo" options={options} sx={{ width: 300 }} renderInput={(params) => <TextField {...params} label="Controllable" />} /> </div> ); }
错误详情
1. value属性类型错误
Type 'string' is not assignable to type 'string[]'.ts(2322) useAutocomplete.d.ts(292, 3): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & AutocompleteProps<string, undefined, undefined, undefined, "div">'
2. onChange回调参数类型错误
Type '(event: any, newValue: string | null) => void' is not assignable to type '(event: SyntheticEvent<Element, Event>, value: string[], reason: AutocompleteChangeReason, details?: AutocompleteChangeDetails<string>) => void'. Types of parameters 'newValue' and 'value' are incompatible. Type 'string[]' is not assignable to type 'string'.ts(2322) useAutocomplete.d.ts(217, 3): The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & AutocompleteProps<string, undefined, undefined, undefined, "div">'
提问者困惑:示例代码中value应为单个字符串,但TypeScript却要求其为字符串数组。
解决方法
问题根源是TypeScript的自动类型推断出现偏差:Autocomplete组件默认会将字符串数组类型的options推断为多选模式,因此强制要求value为数组类型。需要显式指定组件的泛型参数,明确为单选模式。
修改后的代码:
import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; const options = ['Option 1', 'Option 2']; export default function ControllableStates() { const [value, setValue] = React.useState<string | null>(options[0]); const [inputValue, setInputValue] = React.useState(''); return ( <div> <div>{`value: ${value !== null ? `'${value}'` : 'null'}`}</div> <div>{`inputValue: '${inputValue}'`}</div> <br /> {/* 显式指定泛型参数,第二个参数设为false表示单选模式 */} <Autocomplete<string, false> value={value} onChange={(event, newValue: string | null) => { setValue(newValue); }} inputValue={inputValue} onInputChange={(event, newInputValue) => { setInputValue(newInputValue); }} id="controllable-states-demo" options={options} sx={{ width: 300 }} renderInput={(params) => <TextField {...params} label="Controllable" />} /> </div> ); }
补充说明:
- 泛型参数
<string, false>中,string是选项的类型,false表示禁用多选模式; - 也可以通过添加
multiple={false}属性辅助类型推断,但显式指定泛型参数更直接可靠; - 若仍有推断问题,可给
options添加类型标注const options: string[] = ['Option 1', 'Option 2'],进一步明确类型。
内容的提问来源于stack exchange,提问作者user3142695
相关产品推荐
相关产品推荐

