如何让TypeScript函数返回string[]?类型适配问题求助
如何让TypeScript函数返回string[]类型?
当前collectByProperty函数返回类型不符合预期,TypeScript推断数组元素类型为(T[keyof T] extends readonly (infer InnerArr)[] ? InnerArr : T[keyof T])。希望函数能稳定返回string[],同时property参数既能正确约束为对象的键,又不会出现item[property]的属性访问报错。直接将property设为string会导致类型检查失败,尝试用变量存储property也未解决问题。
原代码如下:
interface IMovie { genre: string[]; actors: string[]; } const movies: IMovie[] = [ { genre: ['Action', 'Sci-Fi', 'Adventure'], actors: ['Scarlett Johansson', 'Florence Pugh', 'David Harbour'], } ]; function collectByProperty<T>(arr: T[], property: keyof T): string[] { const array = arr.map((item) => item[property]).flat(); const elem = array[0]; const final = [...new Set(array)]; return final; } const genres = collectByProperty<IMovie>(movies, 'genre'); const actors = collectByProperty<IMovie>(movies, 'actors'); console.log(genres); console.log(actors);
解决方案
通过泛型约束明确指定property对应的属性类型必须为string[],同时优化类型推断:
方案一:带条件类型的严格约束
interface IMovie { genre: string[]; actors: string[]; } const movies: IMovie[] = [ { genre: ['Action', 'Sci-Fi', 'Adventure'], actors: ['Scarlett Johansson', 'Florence Pugh', 'David Harbour'], } ]; // 泛型K约束为T的键,且T[K]必须是string[]类型 function collectByProperty<T, K extends keyof T>(arr: T[], property: K): T[K] extends string[] ? string[] : never { // 利用泛型约束做安全断言 const array = arr.map(item => item[property]).flat() as string[]; return [...new Set(array)]; } const genres = collectByProperty(movies, 'genre'); // 类型自动推断为string[] const actors = collectByProperty(movies, 'actors'); // 类型自动推断为string[] console.log(genres); console.log(actors);
- 新增泛型参数
K,明确property是T的键,同时通过条件类型限制只有属性值为string[]时才能调用该函数 - 对
flat()后的数组做类型断言,因为泛型约束已经确保属性值是string[],所以断言是安全的
方案二:简化版类型断言
interface IMovie { genre: string[]; actors: string[]; } const movies: IMovie[] = [ { genre: ['Action', 'Sci-Fi', 'Adventure'], actors: ['Scarlett Johansson', 'Florence Pugh', 'David Harbour'], } ]; function collectByProperty<T, K extends keyof T>(arr: T[], property: K): string[] { // 用flatMap替代map+flat,直接断言属性值为string[] return [...new Set(arr.flatMap(item => item[property] as string[]))]; } const genres = collectByProperty(movies, 'genre'); const actors = collectByProperty(movies, 'actors'); console.log(genres); console.log(actors);
- 使用
flatMap简化数组处理逻辑 - 通过
as string[]直接断言属性值类型,结合K extends keyof T的约束,保证类型安全 - 函数直接返回
string[]类型,符合需求
内容的提问来源于stack exchange,提问作者Aleksej
相关产品推荐
相关产品推荐

