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

TypeScript条件类型能否实现Integer类型?

实现TypeScript编译时校验的Integer类型

问题分析

你之前编写的条件类型:

type Integer<T extends number> = `${T}` extends `${number}.${number}` ? never : T;

核心思路没问题——通过模板字面量将数值转为字符串,判断是否包含小数点来区分整数和小数。但它是泛型条件类型,必须传入具体的数值类型(比如Integer<5>)才能生效,直接用Integer作为变量类型时,泛型参数无法自动推断,因此只能约束特定整数,而非任意整数。

可行实现方案

TypeScript本身没有原生的整数类型,但可以通过以下方式结合条件类型实现编译时校验:

1. 泛型函数封装(推荐)

用泛型函数捕获赋值的数值,自动推断泛型参数并触发条件类型校验:

type Integer<T extends number> = `${T}` extends `${string}.${string}` ? never : T;

function integer<T extends number>(value: Integer<T>): T {
  return value;
}

// 正常通过编译
const validInt = integer(123);
const validNegInt = integer(-456);

// 编译报错:类型“123.45”不能赋值给类型“never”
const invalidFloat = integer(123.45);
const invalidZeroFloat = integer(0.1);

2. 结合satisfies运算符(TS 4.9+)

如果不想用函数,可利用satisfies配合条件类型实现变量赋值时的校验:

type Integer<T extends number> = `${T}` extends `${string}.${string}` ? never : T;

// 正常通过
const num1 = 789 satisfies Integer<789>;
// 编译报错
const num2 = 789.1 satisfies Integer<789.1>;

3. 品牌类型(Brand Type)+ 运行时断言

如果需要同时兼顾编译时校验和运行时安全,可以结合品牌类型:

type Integer = number & { __brand: 'integer' };

function assertInteger<T extends number>(value: T): asserts value is Integer {
  if (!Number.isInteger(value)) {
    throw new Error(`Expected integer, got ${value}`);
  }
}

// 编译时允许赋值任意number,但调用assertInteger后会缩小类型
let num = 100;
assertInteger(num);
// 此时num的类型为Integer,赋值小数会编译报错
num = 200; // 正常
num = 200.5; // 编译错误

总结

可以通过条件类型实现需求,但需要结合泛型推断、函数封装或satisfies运算符来让条件类型作用于任意整数的赋值场景,而非仅特定数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:40:11