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

如何在TypeScript中声明适配数组索引的自然数类型?

TypeScript中声明自然数类型的几种方案

自然数(非负整数)正好匹配数组索引的合法范围,以下是几种在TypeScript中实现该类型的实用方案:

方案一:品牌类型(Branded Type)结合运行时校验

通过品牌类型标记合法的自然数,同时在运行时确保输入符合要求,兼顾编译时约束和运行时安全:

// 定义品牌类型,用唯一的私有属性标记自然数
type NaturalNumber = number & { __naturalNumberBrand: never };

// 转换函数:将普通number转为NaturalNumber,不符合条件则抛出错误
function toNaturalNumber(n: number): NaturalNumber {
  if (n >= 0 && Number.isInteger(n)) {
    return n as NaturalNumber;
  }
  throw new Error('输入必须是非负整数');
}

// 使用示例
const validIndex = toNaturalNumber(3);
const arr = ['a', 'b', 'c', 'd'];
console.log(arr[validIndex]); // 合法

// 以下代码会报错:编译时类型不匹配,运行时也会抛出错误
// arr[toNaturalNumber(-1)];
// arr[toNaturalNumber(2.5)];

这种方案的优势是严格区分自然数和普通number,只要类型是NaturalNumber,就能确保它是合法的数组索引。

方案二:编译时有限范围自然数类型

如果你的数组索引有明确的上限(比如0到99),可以用递归类型生成固定范围的自然数,纯编译时约束:

// 递归生成自然数类型的辅助类型
type _NaturalRange<Max extends number, Acc extends number[] = []> = 
  Acc['length'] extends Max 
    ? Acc[number] 
    : _NaturalRange<Max, [...Acc, Acc['length']]>;

// 生成0到99的自然数类型
type NaturalNumber0To99 = _NaturalRange<100>;

// 使用示例:限制数组索引必须在0-99之间
function getArrayItem<T>(arr: T[], index: NaturalNumber0To99): T {
  return arr[index];
}

getArrayItem([1, 2, 3], 2); // 合法
// 以下代码编译时报错
// getArrayItem([1,2,3], -1);
// getArrayItem([1,2,3], 100);

注意:这种方法受限于TypeScript的递归深度限制,不适合生成过大范围的类型。

方案三:类型守卫(Type Guard)

通过类型守卫在运行时校验输入,编译时自动缩小类型范围,适合动态场景:

// 类型守卫函数:判断输入是否为自然数
function isNaturalNumber(n: unknown): n is number {
  return typeof n === 'number' && n >= 0 && Number.isInteger(n);
}

// 使用示例
const arr = [10, 20, 30];
const maybeIndex: unknown = 1;

if (isNaturalNumber(maybeIndex)) {
  console.log(arr[maybeIndex]); // 合法,编译时自动识别maybeIndex为自然数类型
} else {
  console.error('索引必须是非负整数');
}

这种方案灵活度高,无需提前转换类型,适合处理动态传入的索引值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:41:16