skip to Main Content

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?

2

Answers


  1. You could make some superior/inferior condition :

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

    Hope I could help !

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search