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

TypeScript如何基于属性值限制另一属性类型并实现泛型推断

解决方案

首先先给出通用的固定长度元组工具类型实现:

type Tuple<T, N extends number, R extends T[] = []> = R['length'] extends N ? R : Tuple<T, N, [...R, T]>;

TypeScript 暂不支持直接在标注泛型接口类型的变量赋值时,从赋值内容自动推断泛型参数,你可以用以下两种常用方案实现需求:

方案1:泛型辅助函数(推荐)

利用 TypeScript 函数调用时的自动泛型推断能力,无需手动传入泛型参数即可完成校验:

// 原有泛型接口保持不变
interface Rating<T extends 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10> {
  maxRating: T;
  exampleResults: Tuple<number, T>;
}

// 新增泛型工具函数
function defineRating<T extends 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10>(rating: Rating<T>) {
  return rating;
}

// 直接使用,TypeScript 会根据maxRating自动推断泛型参数,校验exampleResults长度
const rating = defineRating({
  maxRating: 5,
  exampleResults: [0, 0, 0, 1, 4],
});

如果exampleResults的长度和maxRating取值不匹配,TypeScript 会直接抛出类型错误。

方案2:预生成联合类型

如果不想引入额外的工具函数,可以预先生成所有可能的Rating场景的联合类型,直接标注类型即可使用:

type MaxRating = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;

type Rating = {
  [T in MaxRating]: {
    maxRating: T;
    exampleResults: Tuple<number, T>;
  }
}[MaxRating];

// 直接标注类型使用,无需传入泛型参数
const rating: Rating = {
  maxRating: 5,
  exampleResults: [0, 0, 0, 1, 4],
};

该方案的优势是使用时更简洁,不需要调用函数,弊端是如果后续需要扩展maxRating的取值范围,需要同步修改MaxRating联合类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:24:07