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

如何在TypeScript低版本中基于已有接口属性名创建带后缀的新接口?

在TypeScript 4.1以下版本实现关联属性接口的方案

由于TypeScript 4.1才引入键重映射和模板字面量类型这两个核心特性,在更低版本里确实没办法完全自动生成带Index后缀的属性名,但我们可以通过几种变通方案来减少重复代码、降低出错概率:

方案一:用枚举统一管理属性名

通过枚举把原属性和带后缀的属性名统一维护,避免手动拼写错误,同时让两个接口的属性名形成明确关联:

// 枚举定义所有需要的属性名,包含原属性和对应Index后缀的属性
enum PropKeys {
  PropOne = 'propOne',
  PropOneIndex = 'propOneIndex',
  PropTwo = 'propTwo',
  PropTwoIndex = 'propTwoIndex',
  PropThree = 'propThree',
  PropThreeIndex = 'propThreeIndex',
}

interface Int1 {
  [PropKeys.PropOne]: string;
  [PropKeys.PropTwo]?: number;
  [PropKeys.PropThree]?: Date;
}

interface Int2 {
  [PropKeys.PropOneIndex]: number;
  [PropKeys.PropTwoIndex]?: number;
  [PropKeys.PropThreeIndex]?: number;
}

这个方案的优势是属性名统一管控,不会出现拼写失误;唯一的小缺点是当Int1新增属性时,需要同步在枚举和Int2里添加对应的Index项。

方案二:用条件类型关联属性可选性

如果更关注Int2属性的可选性和Int1保持自动同步,我们可以借助条件类型来实现这一点,属性名虽然还是要手动写,但可选性会自动跟随Int1变化:

interface Int1 {
  propOne: string;
  propTwo?: number;
  propThree?: Date;
}

// 通过条件类型自动推导Int2属性的可选性
type Int2 = {
  propOneIndex: number;
} & (undefined extends Int1['propTwo'] ? { propTwoIndex?: number } : { propTwoIndex: number })
& (undefined extends Int1['propThree'] ? { propThreeIndex?: number } : { propThreeIndex: number });

比如如果后续把Int1里的propTwo改成必填项,Int2的propTwoIndex会自动变成必填,不需要手动修改。

方案三:辅助类型做事后验证(低版本兼容版)

如果想确保Int2完全符合规则,我们可以写一个辅助类型来做校验,一旦Int2的属性名、类型或可选性不符合要求,TypeScript就会报错:

interface Int1 {
  propOne: string;
  propTwo?: number;
  propThree?: Date;
}

// 针对低版本TS的辅助验证类型,手动检查每个属性的关联关系
type ValidateInt2<T> = {
  propOne: 'propOneIndex' extends keyof T ? T['propOneIndex'] extends number ? true : false : false;
  propTwo: 'propTwoIndex' extends keyof T ? T['propTwoIndex'] extends number ? undefined extends Int1['propTwo'] ? undefined extends T['propTwoIndex'] : true : false : false;
  propThree: 'propThreeIndex' extends keyof T ? T['propThreeIndex'] extends number ? undefined extends Int1['propThree'] ? undefined extends T['propThreeIndex'] : true : false : false;
};

// 定义Int2后,通过辅助类型验证结构是否正确
interface Int2 {
  propOneIndex: number;
  propTwoIndex?: number;
  propThreeIndex?: number;
}

// 如果Int2不符合要求,这里会显示对应属性为false
type CheckInt2Validity = ValidateInt2<Int2>;

这个方案相当于给Int2加了一层类型校验,能有效避免手动编写时的疏漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:37:46