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

TypeScript中实现支持按名称索引且保留类型的泛型回调工厂

如何实现仅约束指定索引属性类型的泛型回调工厂?

你的需求完全可以实现!你最初的思路方向是对的,只是泛型约束的写法太严格了——之前的Dateable<T>要求对象的所有属性都是DateTime,但你真正需要的是只约束指定的单个属性为DateTime类型。

正确的泛型回调工厂写法

我们可以通过Record<K, DateTime>来精准约束泛型,确保对象的指定键K对应的值是DateTime,而其他属性可以是任意类型:

const compareByClosestTo = <T extends Record<K, DateTime>, K extends keyof T>(
  key: K, 
  date: DateTime
) => (l: T, r: T) => 
  Math.abs(l[key].diff(date).milliseconds) - Math.abs(r[key].diff(date).milliseconds);

为什么这个写法能满足需求?

  • T extends Record<K, DateTime>:表示T可以是任意对象,但必须包含K这个键,且该键对应的值类型为DateTime,其他属性无任何限制。
  • 调用时TypeScript会自动推导类型:比如你写candidates.sort(compareByClosestTo("recieved", date)),TS会自动识别K为"recieved",并检查candidates中每个元素的"recieved"属性是否为DateTime类型,全程保证类型安全。

对比你后来的写法

你后续实现的sortByClosest函数是直接对数组做排序操作,虽然能工作,但复用性不如回调工厂——如果需要在多个不同数组的排序场景中使用“按指定日期属性找最近值”的逻辑,回调工厂的写法可以直接把排序函数传递给Array.sort(),灵活性更高。

验证调用示例

假设你有这样的数组:

interface Candidate {
  id: number;
  name: string;
  recieved: DateTime;
}

const candidates: Candidate[] = [/* ... */];
const targetDate = DateTime.now();

// 完全符合你的预期写法,且类型检查正常
candidates.sort(compareByClosestTo("recieved", targetDate));

这样就完美实现了你想要的“按名称索引且保留类型信息”的泛型回调工厂啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:57:35