TypeScript:带泛型的函数类型赋值箭头函数时泛型未找到,如何继承组件泛型?
我有一个已声明的带泛型的函数类型,想要将其赋值给一个命名箭头函数,代码示例如下:
import { AutocompleteProps } from '@material-ui/lab/Autocomplete'; const itemToString: AutocompleteProps< T, Multiple, DisableClearable, FreeSolo >['getOptionLabel'] = (i) => (typeof i === 'string' ? i : (i?.name as string)) || '';
但TypeScript提示无法找到T, Multiple, DisableClearable, FreeSolo这些泛型,请问我应该在哪里定义它们?
补充说明:我希望这个函数能传递给Autocomplete组件的getOptionLabel属性,并继承该组件的泛型,这是否可行?还是应该采用Rajiv的答案?
另外,我尝试了如下写法但无法正常工作:
const itemToString: < T extends Entity, Multiple extends boolean, DisableClearable extends boolean, FreeSolo extends boolean > AutocompleteProps< T, Multiple, DisableClearable, FreeSolo >['getOptionLabel'] = (i) => (typeof i === 'string' ? i : (i?.name as string)) || '';
1. 正确定义泛型箭头函数的方式
你需要把泛型参数绑定到箭头函数本身,而不是放在类型注解里。TypeScript规定,箭头函数的泛型要写在函数参数括号的左侧,而不是类型注解的<>中。以下是符合语法的写法:
import { AutocompleteProps } from '@material-ui/lab/Autocomplete'; const itemToString = <T, Multiple extends boolean, DisableClearable extends boolean, FreeSolo extends boolean>( i: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>['getOptionLabel'] extends (arg: infer U) => any ? U : never ): string => { return typeof i === 'string' ? i : (i?.name as string) || ''; };
2. 更简洁的兼容方案(推荐)
如果你只需要让函数适配Autocomplete组件的getOptionLabel属性,不需要显式声明所有泛型参数。可以直接让函数的类型匹配getOptionLabel的核心约束:接收选项(泛型T或字符串,当FreeSolo为true时)并返回字符串:
import { AutocompleteProps } from '@material-ui/lab/Autocomplete'; const itemToString: <T>(option: T | string) => string = (option) => { return typeof option === 'string' ? option : (option?.name as string) || ''; };
这种写法下,当你把itemToString传递给Autocomplete组件时,TypeScript会自动根据组件的泛型参数T推断option的具体类型,完全满足“继承组件泛型”的需求。
3. 你之前写法失效的原因
你尝试把泛型参数写在类型注解中的方式不符合TypeScript语法规则——泛型参数必须绑定到函数实体,而不是单独的类型注解部分。箭头函数的泛型声明位置是固定的,不能放在类型注解的<>里。
关于继承组件泛型的可行性
完全可行,上述第二种写法就是让函数兼容Autocomplete的泛型约束,组件使用不同的T类型时,函数会自动适配对应的选项类型,无需额外定义泛型参数。
内容的提问来源于stack exchange,提问作者Bill

