You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:55:27