MUI Autocomplete TypeScript 实现双字段搜索及自定义UI报错TS2339求解
问题原因
- 你没有给
suggestion数组显式声明TypeScript类型,TS无法推断数组内元素的字段结构,默认将元素判定为never类型,访问name/companyName字段就会触发TS2339错误 - MUI v5的
renderOption回调参数格式错误:第一个参数是需要绑定到选项DOM的属性对象,第二个才是当前遍历的option数据 - 开启
freeSolo属性后,Autocomplete的value可能是你传入的对象类型,也可能是用户自由输入的字符串,需要额外做类型兼容处理
解决步骤
1. 定义数据源类型
先声明成员数据的TS类型,给suggestion数组绑定类型:
interface Member { __typename: "Member"; id: string; name: string; companyName: string; } // 给suggestion数组指定类型,如果是接口返回的数据,赋值时也需要对应声明类型 const suggestion: Member[] = [...你的数据源]
2. 修正组件属性写法
调整renderOption参数,同时配置搜索规则支持同时匹配姓名和公司名:
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; // 配置搜索规则:同时匹配name和companyName字段 const filterOptions = createFilterOptions<Member>({ stringify: (option) => `${option.name} ${option.companyName}`, }); <Autocomplete id="free-solo-demo" freeSolo options={suggestion} filterOptions={filterOptions} // 兼容freeSolo下value可能为字符串的情况 getOptionLabel={(option) => { if (typeof option === 'string') return option; return `${option.name} ${option.companyName}`; }} // 修正renderOption参数,第一个li属性必须绑定才能保证默认交互、样式正常 renderOption={(props, option) => { return ( <li {...props}> <h1>{`${option.name}: ${option.companyName}`}</h1> </li> ); }} onChange={(event, value) => { // value可能是Member对象也可能是用户输入的字符串,根据业务逻辑处理 if (value && typeof value !== 'string') { HandleUserProfile(value); } else { // 这里可以自定义处理用户自由输入的场景 HandleUserProfile({ name: value, companyName: '' } as Member); } }} renderInput={(params) => ( <TextField {...params} placeholder="Search..." onChange={handleChange} /> )} />
如果你不需要用户自由输入不在选项列表内的内容,可以直接删掉
freeSolo属性,就不需要额外处理字符串类型的value,逻辑会更简单。
内容的提问来源于stack exchange,提问作者DEV
相关产品推荐
相关产品推荐

