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

TypeScript 如何定义属性名匹配固定模式且含固定字段的type

TypeScript 动态键类型实现方案

TS 4.4及以上版本已经原生支持模板字面量作为索引签名的键类型,完全可以实现你要的效果,无需宽泛索引签名或手动枚举。

核心实现代码

// 定义匹配id+数字规则的键类型
type IdPrefixedNumberKey = `id${number}`;

// 组合固定属性和动态属性
type TargetType = {
  id: number;
  somethingElse: string;
  anotherOne: number;
} & {
  [Key in IdPrefixedNumberKey]?: number;
};

校验效果说明

  • 符合规则的用例不会报错:
const validSample: TargetType = {
  id: 101,
  somethingElse: "demo",
  anotherOne: 202,
  id3: 303,
  id10086: 12345
};
  • 不符合规则的用例会触发TS编译报错:
    • 出现idStr、id_123这类不符合id+数字格式的键
    • idxxx格式的键对应的值不是number类型
    • 缺少三个必填属性,或必填属性类型错误

低版本TS兼容方案

如果使用的TS版本低于4.4,不支持模板字面量索引签名,最优替代方案是结合宽松基础类型+类型守卫做双重校验:

// 基础类型声明,固定属性严格校验,其他属性暂设为unknown
type LegacyTargetType = {
  id: number;
  somethingElse: string;
  anotherOne: number;
} & Record<string, unknown>;

// 类型守卫函数,运行时校验所有动态键规则
function isValidTarget(obj: unknown): obj is LegacyTargetType {
  if (typeof obj !== "object" || obj === null) return false;
  const castObj = obj as LegacyTargetType;

  // 校验必填固定属性
  if (typeof castObj.id !== "number") return false;
  if (typeof castObj.somethingElse !== "string") return false;
  if (typeof castObj.anotherOne !== "number") return false;

  // 校验所有id开头的键符合规则
  for (const [key, val] of Object.entries(obj)) {
    if (!key.startsWith("id")) continue;
    const numSuffix = key.slice(2);
    // 仅校验符合id+数字格式的键的类型
    if (/^\d+$/.test(numSuffix) && typeof val !== "number") {
      return false;
    }
  }
  return true;
}

使用时先调用类型守卫做校验,后续代码即可获得完整的类型提示和校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:45:10