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

实现类Lodash的Iteratee类型时遇TypeScript类型赋值错误求助

解决TypeScript中Iteratee类型赋值错误问题

错误原因

TypeScript无法在泛型上下文里自动推断T[KeysCorrespondingToValueType<T, number>]必然是number类型。尽管我们的KeysCorrespondingToValueType类型逻辑上已经筛选出了值为number的对象键,但编译器无法回溯该类型定义的约束关系,因此无法确认item[iteratee]的类型符合返回值要求。

解决方案

方案1:使用类型断言(简洁高效)

由于Iteratee<T, number>已经约束了:要么是返回number的函数,要么是对应值为number的对象键,因此可以安全地对item[iteratee]做类型断言,告诉编译器该值确实是number:

type KeysCorrespondingToValueType<T, V> = {
  [K in keyof T]-?: T[K] extends V ? K : never;
}[keyof T];

type Iteratee<T, V> = KeysCorrespondingToValueType<T, V> | ((item: T) => V);

function getNumericValueFromIteratee<T>(
  item: T,
  iteratee: Iteratee<T, number>
): number {
  return typeof iteratee === 'function' 
    ? iteratee(item) 
    : item[iteratee] as number;
}

方案2:拆分泛型参数(类型更严谨)

引入额外的泛型参数K明确键的类型,让编译器直接关联键与对应属性值的类型约束,无需断言:

type KeysCorrespondingToValueType<T, V> = {
  [K in keyof T]-?: T[K] extends V ? K : never;
}[keyof T];

type Iteratee<T, V, K extends KeysCorrespondingToValueType<T, V>> = K | ((item: T) => V);

function getNumericValueFromIteratee<T, K extends KeysCorrespondingToValueType<T, number>>(
  item: T,
  iteratee: Iteratee<T, number, K>
): number {
  return typeof iteratee === 'function' 
    ? iteratee(item) 
    : item[iteratee];
}

方案3:自定义类型守卫(带运行时检查)

如果需要额外的运行时验证,可以定义类型守卫函数,确保键对应的属性值类型符合要求:

type KeysCorrespondingToValueType<T, V> = {
  [K in keyof T]-?: T[K] extends V ? K : never;
}[keyof T];

type Iteratee<T, V> = KeysCorrespondingToValueType<T, V> | ((item: T) => V);

function isKeyOfValueType<T, V>(item: T, key: keyof T): key is KeysCorrespondingToValueType<T, V> {
  return typeof item[key] === typeof ({} as V);
}

function getNumericValueFromIteratee<T>(
  item: T,
  iteratee: Iteratee<T, number>
): number {
  if (typeof iteratee === 'function') {
    return iteratee(item);
  } else if (isKeyOfValueType<T, number>(item, iteratee)) {
    return item[iteratee];
  }
  throw new Error('Invalid iteratee: must be a numeric property key or number-returning function');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:56:35