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

如何为可接收返回字符串/对象数组的函数及Angular指令Input做类型标注

问题原因

你没有给泛型T添加类型约束,TypeScript无法推断T的可能类型,所以访问字符串的toLowerCase()方法、对象的value属性时,都会报类型不存在的错误。同时你原来的运行时类型判断没有和TypeScript的类型收窄逻辑关联,TS无法识别分支内的变量类型。

解决方案

完整修改后的代码如下:

// 定义对象数组的项类型约束
interface FilterOption {
  value: string;
  [key: string]: any; // 兼容对象的其他自定义属性
}

// 给泛型T添加类型约束,仅允许传入字符串或符合FilterOption结构的对象
export class SelectFilteringDirective<T extends string | FilterOption> {
  @Input() readonly optionsList: T[] = [];
  @Output() filteredList = new EventEmitter<T[]>();

  constructor() {}

  @HostListener('keyup', ['$event'])
  onKeyup(event: Event): void {
    this.filteredList.emit(
      this.filterList(
        this.optionsList,
        (event.target as HTMLInputElement).value
      )
    );
  }

  private filterList(data: T[], value: string): T[] {
    // 处理空数组边界情况,避免读取data[0]报错
    if (!data.length) return [];
    const searchKey = value.toLowerCase();

    // 类型谓词:告诉TS如果返回true,item就是string类型
    const isStringItem = (item: T): item is string => typeof item === 'string';
    // 类型谓词:告诉TS如果返回true,item就是FilterOption类型
    const isObjectItem = (item: T): item is FilterOption => typeof item === 'object' && 'value' in item;

    return [...data].filter(item => {
      if (isStringItem(item)) {
        return item.toLowerCase().includes(searchKey);
      }
      if (isObjectItem(item)) {
        return item.value.toLowerCase().includes(searchKey);
      }
      return false;
    })
  }
}

核心修改点

  • 给泛型T添加了extends string | FilterOption约束,限制输入数组的项只能是两种允许的类型
  • 新增了带类型谓词的类型判断函数,让TypeScript可以正确收窄每个分支的变量类型,不会再报属性不存在的错误
  • 处理了空数组的边界场景,避免空列表时运行时报错
  • 把filterList的返回值从any改为了T[],符合类型安全要求

内容的提问来源于stack exchange,提问作者JanuszFrontEnd'u

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:24:03