TypeScript中OptionType缺失索引签名报错的解决方案问询
解决React Autocomplete组件的TypeScript索引签名类型错误
问题场景
在使用React Autocomplete组件的TypeScript代码中,{optionList[index].map((el) => tag[el])}处触发类型错误,提示:
In the Option Type an index signature containing parameters of the type could not be found
相关代码片段:
type SubOptionType = { year: number zest: number } type OptionType = Partial<SubOptionType> & { id: number label: string } const optionList = useMemo(() => { return option.map((opt) => Object.keys(opt).filter((keyVal) => !removeItems.includes(keyVal))) }, [option]) <Autocomplete renderTags={(tagValue) => tagValue.map((tag: OptionType, index) => ( <LabelChips key={tag.id} size="small" text={tag.label} > {optionList[index].map((el) => tag[el])} </LabelChips> )) } />
解决方案
方案1:为OptionType添加索引签名
TypeScript报错的核心原因是Object.keys()返回string[]类型,但OptionType未定义索引签名,无法确认tag[el]的访问合法性。我们可以给OptionType添加兼容所有键类型的索引签名:
type SubOptionType = { year: number zest: number } // 添加索引签名,允许string类型的键,对应值覆盖所有字段的类型 type OptionType = Partial<SubOptionType> & { id: number label: string [key: string]: number | string | undefined }
方案2:明确optionList的类型为Array<Array<keyof OptionType>>
如果不想放宽OptionType的类型约束,可以通过标注optionList的类型,让TypeScript知道el是OptionType的合法键:
type SubOptionType = { year: number zest: number } type OptionType = Partial<SubOptionType> & { id: number label: string } // 明确optionList类型,并将过滤后的键断言为OptionType的合法键 const optionList = useMemo<Array<Array<keyof OptionType>>>(() => { return option.map((opt) => Object.keys(opt).filter((keyVal) => !removeItems.includes(keyVal)) as Array<keyof OptionType> ) }, [option])
修改后完整代码示例(方案2)
type SubOptionType = { year: number zest: number } type OptionType = Partial<SubOptionType> & { id: number label: string } const option = [ { id: 1, label: 'Casablanca', zest: 3000, year: 1950 }, { id: 2, label: 'Psycho', zest: 3000, year: 1950 }, { id: 3, label: 'The Green Mile', zest: 3000, year: 1950 }, { id: 4, label: 'The Intouchables', zest: 3000, year: 1950 }, ] const optionList = useMemo<Array<Array<keyof OptionType>>>(() => { return option.map((opt) => Object.keys(opt).filter((keyVal) => !removeItems.includes(keyVal)) as Array<keyof OptionType> ) }, [option]) <Autocomplete renderTags={(tagValue) => tagValue.map((tag: OptionType, index) => ( <LabelChips key={tag.id} size="small" text={tag.label} > {optionList[index].map((el) => tag[el])} </LabelChips> )) } />
内容的提问来源于stack exchange,提问作者김찬영
相关产品推荐
相关产品推荐

