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

TypeScript:如何定义含唯一确定字段的对象数组类型?

关于TypeScript中排序函数的参数类型定义问题

场景示例

我有如下对象数组:

const obj = [
  { createdAt: "2022-10-25T08:06:29.392Z", updatedAt: "2022-10-25T08:06:29.392Z"},
  { createdAt: "2022-10-25T08:06:29.392Z", animal: "cat"}
]

我想编写一个按createdAt字段排序的函数,该字段是数组中每个对象唯一确定存在的字段,函数代码如下:

export const sortArrayByCreatedAt = (arr: TypeArr) => {
    return arr.sort(function (a, b) {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

我的疑问

我当前对参数arr的类型定义如下:

type TypeArr = {
  createdAt: string
}[]

这种仅定义已知字段的方式是否为最佳实践?我担心其他开发者看到该函数会误以为数组元素仅包含createdAt字段,但暂未找到更优方案。


解决方案与分析

1. 更合理的类型定义

你最初的类型定义存在一个问题:它会让TypeScript把数组元素判定为仅包含createdAt的对象,丢失了原对象的其他字段类型信息。更优的方案是用泛型约束来定义参数类型:

export const sortArrayByCreatedAt = <T extends { createdAt: string }>(arr: T[]) => {
    return arr.sort((a, b) => {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

如果想单独抽离类型,也可以先定义一个基础类型,再用泛型约束:

type HasCreatedAt = {
  createdAt: string;
};

export const sortArrayByCreatedAt = <T extends HasCreatedAt>(arr: T[]) => {
    return arr.sort((a, b) => {
        return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
    });
};

2. 泛型约束的优势

  • 保留完整类型信息:传入的数组元素不管有多少额外字段(比如updatedAt、animal),返回的数组都会保留这些字段的类型,不会出现后续使用时类型报错的情况。
  • 避免误解:其他开发者看到T extends { createdAt: string }时,能立刻明白这个函数只要求对象必须有createdAt字段,完全允许存在其他属性,不会产生“元素只能有createdAt”的误解。
  • 复用性更强:同一个排序函数可以直接用在任何包含createdAt字段的对象数组上,不用为不同结构的数组重复写排序逻辑。

3. 关于“仅定义已知字段”的实践

你最初的写法并非最佳实践,因为它会在类型层面“阉割”掉原对象的额外字段,虽然运行时不会有问题,但不符合TypeScript的类型安全设计理念——我们希望类型能准确反映数据结构,而不是刻意缩小范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:40:31