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

TypeScript中如何定义固定条目数、键值均为number类型的对象类型

TypeScript 固定条目数number键值对象类型实现

原写法存在两个核心问题:

  • TypeScript同一类型下,number/string类型的索引签名仅允许定义1次,重复定义会直接抛出语法错误
  • 索引签名的作用是约束所有匹配该键类型的属性的值类型,和对象包含的键数量无关,哪怕仅写1次[key: number]: number,也会允许对象存在任意多个number类型的键,无法满足固定2个条目的要求。

以下是不同场景下的正确实现:

已知固定队伍ID场景

如果参赛的两个队伍ID是固定可预知的,不需要动态键,直接定义明确的对象结构即可,无需使用索引签名:

// 示例:参赛队伍固定为ID 1001、1002
type MatchResult = {
  1001: number;
  1002: number;
}

// 校验通过
const finalResult: MatchResult = {
  1001: 3,
  1002: 1
}

需类型层面强制约束2个键值对场景

如果队伍ID为动态number类型,且需要在类型检查阶段就强制对象只能有2个键、值均为number,可通过泛型结合键集合长度校验实现:

type ExactTwoNumEntries<T> = 
  T extends Record<keyof T, number>
    ? keyof T extends number
      ? [keyof T] extends [infer K extends PropertyKey]
        ? { 0: unknown, 1: unknown }[Extract<K, number>] extends never
          ? never
          : [K, K, K] extends [K, K, infer Third]
            ? Third extends K
              ? never
              : T
            : never
          : never
      : never
    : never;

// 用法:声明变量时传入对象结构做校验
const validResult: ExactTwoNumEntries<{2: 3, 5: 1}> = {2:3, 5:1}; // 校验通过
const lackEntry: ExactTwoNumEntries<{2:3}> = {2:3}; // 类型报错,条目数量不足
const tooManyEntries: ExactTwoNumEntries<{2:3, 5:1, 7:0}> = {2:3,5:1,7:0}; // 类型报错,条目超出2个
const wrongValueType: ExactTwoNumEntries<{2: string, 5:1}> = {2:"3",5:1}; // 类型报错,值不是number类型

实际业务开发推荐方案

绝大多数比赛结果场景下,队伍ID都是接口动态返回的,类型阶段无法预知具体ID值,不需要过度追求类型层面的精确数量约束,直接使用单个number索引签名定义类型,将固定2个条目的校验放在运行时逻辑处理即可,实现成本最低且完全覆盖业务需求:

type MatchResult = Record<number, number>;

// 运行时类型守卫,校验是否为符合要求的两队比赛结果
function isValidMatchResult(result: unknown): result is MatchResult {
  if (typeof result !== 'object' || result === null) return false;
  const entries = Object.entries(result as object);
  if (entries.length !== 2) return false;
  return entries.every(([key, value]) => !Number.isNaN(Number(key)) && typeof value === 'number');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:06:15