乐闻世界logo
搜索文章和话题

Is there a way to represent a non-negative integer in TypeScript so that the compiler would prevent using fractions and negatives?

4 个月前提问
3 个月前修改
浏览次数32

1个答案

1

在TypeScript中,原生并不直接支持区分非负整数和其他类型的数字,因为TypeScript的基础类型中只有number,它包括了整数、浮点数、正数、负数等。但是,我们可以通过一些技术手段来尽可能地保证变量在运行时保持为非负整数。

方法1:类型别名和运行时检查

虽然TypeScript不能在编译时强制实现非负整数,我们可以定义一个类型别名来语义上表示这个意图,并通过函数在运行时强制检查。

typescript
type NonNegativeInteger = number; function asNonNegativeInteger(x: any): NonNegativeInteger { if (typeof x !== 'number' || !Number.isInteger(x) || x < 0) { throw new Error("Value must be a non-negative integer"); } return x; } // 使用函数包装确保类型安全 let age: NonNegativeInteger = asNonNegativeInteger(25); let invalidAge = asNonNegativeInteger(-5); // 这里会抛出错误

方法2:利用类型守卫

我们可以定义一个类型守卫来帮助TypeScript理解某个变量是否是非负整数。

typescript
function isNonNegativeInteger(x: number): x is NonNegativeInteger { return Number.isInteger(x) && x >= 0; } function processAge(age: number) { if (isNonNegativeInteger(age)) { console.log(`Valid age: ${age}`); } else { console.log("Invalid age. Age must be a non-negative integer."); } } processAge(30); // 输出: Valid age: 30 processAge(-1); // 输出: Invalid age. Age must be a non-negative integer.

方法3:使用额外的库

有一些TypeScript扩展库,如io-tsruntypes,可以在运行时执行类型检查,同时提供类型系统的集成。

typescript
import * as t from 'io-ts'; const NonNegativeInteger = t.brand( t.number, (n): n is t.Branded<number, { readonly NonNegativeInteger: unique symbol }> => Number.isInteger(n) && n >= 0, 'NonNegativeInteger' ); const decodeAge = NonNegativeInteger.decode(30); if (decodeAge._tag === 'Right') { console.log(`Valid age: ${decodeAge.right}`); } else { console.log("Invalid age."); }

总结

虽然TypeScript不能直接在编译时区分非负整数和其他数字,我们可以通过运行时检查、类型守卫和使用第三方库来尽可能保证这一点。这些方法有助于在开发过程中增加安全性和健壮性。

2024年6月29日 12:07 回复

你的答案