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

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

1个答案

1

In TypeScript, the native type system does not directly support representing non-negative integers separately from other numeric types because TypeScript's base type is only number, which encompasses integers, floating-point numbers, positive numbers, and negative numbers. However, we can use certain techniques to ensure that variables remain non-negative integers at runtime.

Method 1: Type Alias and Runtime Checks

Although TypeScript cannot enforce non-negative integers at compile time, we can define a type alias to semantically represent this intent and enforce checks at runtime using functions.

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; } // Wrap with function to ensure type safety let age: NonNegativeInteger = asNonNegativeInteger(25); let invalidAge = asNonNegativeInteger(-5); // This will throw an error

Method 2: Using Type Guards

We can define a type guard to help TypeScript understand whether a variable is a non-negative integer.

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); // Output: Valid age: 30 processAge(-1); // Output: Invalid age. Age must be a non-negative integer.

Method 3: Using Additional Libraries

There are some TypeScript extension libraries, such as io-ts and runtypes, that can perform runtime type checks while integrating with the type system.

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."); }

Summary

Although TypeScript cannot directly enforce non-negative integers at compile time, we can use runtime checks, type guards, and third-party libraries to ensure this. These methods help enhance safety and robustness in development.

2024年6月29日 12:07 回复

你的答案