1

I have the following props interface in my component:

export interface ComponentProps {
  title: string;
  value: number;
}

However, I need to veryfy that this value is a number in range from 0 to 24.

The only way I could find to do that so far is to use a union type:

value: 0 | 1 | 2 ... | 24;

Looks ugly... Is there a more elegant way to do that?

Igal
  • 5,833
  • 20
  • 74
  • 132
  • Seeing as you only need a range starting from 0, you could also use a simpler solution like this: https://tsplay.dev/N9jdVm – kelsny Mar 21 '23 at 13:48

2 Answers2

1

The technical term for this sort of thing (a number that's in a specific range) is "dependent types", which is not something that TypeScript attempts to do.

Even if you make a union (either manually or with recursion), it probably won't be much fun, because TypeScript doesn't attempt to track the invariants.

// Error: Type 'number' is not assignable to type 'Hour'.
const q: Hour = 21 + 1;

You could add simple range validation yourself:

function MyComponent({value}: ComponentProps) {
  assert(value >= 0 && value <= 24);

You could enforce this more strictly with a newtype, similar to @Lucas Maracaipe's suggestion:

type Hour = number & { readonly __tag: unique symbol };
function validateHour(value: number): Hour {
  if (value < 0 || value > 24) {
    throw new Error('Hour must be between 0 and 24');
  }
  return value as Hour;
}

export interface ComponentProps {
  title: string;
  value: Hour;
}

Finally, if you really wanted, you could use React's prop-types. Prop types are almost completely obsoleted by TypeScript, and I wouldn't recommend them, but their ability to do arbitrary runtime validation is something that TypeScript's type system can't do.

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
0

You could make some superior/inferior condition :

if ( value >= 0 && value < 25 ){
   ...doSomething
}

Hope I could help !

Hades
  • 75
  • 6