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

如何解构泛型以验证对象属性存在(支持嵌套且不约束T)?

实现支持属性访问的通用二分查找函数

核心需求拆解

  • 兼容原始类型数组(直接用元素值查找)与对象数组(通过lambda提取属性,支持嵌套属性)
  • 利用递归泛型约束属性访问路径,确保访问的属性必然存在于对象类型中
  • 不扩展泛型T的类型范围,保持输入类型的通用性
  • 自动推导目标属性的类型U,避免重复编写相似逻辑的重载函数

实现方案(TypeScript)

// 递归定义属性路径类型,确保访问的属性合法存在
type PropertyPath<T, U> = T extends U 
  ? (item: T) => U
  : {
      [K in keyof T]: PropertyPath<T[K], U> extends infer F 
        ? F extends (item: any) => U 
          ? (item: T) => ReturnType<F> 
          : never 
        : never
    }[keyof T];

// 通用二分查找函数
function binarySearch<T, U>(
  arr: T[],
  target: U,
  getValue: PropertyPath<T, U> = (item: any) => item as U
): number {
  let left = 0;
  let right = arr.length - 1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    const currentValue = getValue(arr[mid]);

    if (currentValue === target) {
      return mid;
    } else if (currentValue < (target as any)) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }

  return -1;
}

使用示例

1. 原始类型数组查找

const nums = [2, 4, 6, 8, 10];
const numIndex = binarySearch(nums, 6);
console.log(numIndex); // 输出: 2

2. 对象数组(单层属性)

interface Book {
  id: number;
  title: string;
}

const books: Book[] = [
  { id: 1, title: "TypeScript实战" },
  { id: 3, title: "前端工程化" },
  { id: 5, title: "React设计模式" }
];
const bookIndex = binarySearch(books, 3, (book) => book.id);
console.log(bookIndex); // 输出: 1

3. 对象数组(嵌套属性)

interface Author {
  name: string;
  contact: {
    email: string;
  };
}

interface NestedBook {
  id: number;
  author: Author;
}

const nestedBooks: NestedBook[] = [
  { id: 1, author: { name: "张三", contact: { email: "zhangsan@example.com" } } },
  { id: 2, author: { name: "李四", contact: { email: "lisi@example.com" } } },
  { id: 3, author: { name: "王五", contact: { email: "wangwu@example.com" } } }
];
const nestedIndex = binarySearch(nestedBooks, "lisi@example.com", (book) => book.author.contact.email);
console.log(nestedIndex); // 输出: 1

关键细节说明

  • 递归泛型PropertyPath:自动校验lambda的属性访问路径,若访问不存在的属性,TypeScript会直接抛出类型错误,保证类型安全
  • 默认属性提取器:当未传入第三个参数时,默认直接返回数组元素本身,完美适配原始类型数组的场景
  • 无冗余重载:通过条件类型实现原始类型与对象类型的兼容,无需编写多个重载函数,保持函数的简洁性与通用性

内容的提问来源于stack exchange,提问作者jumbeldliam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:45:31