Declaring string type with min/max length in typescript

后端 未结 1 1491
小鲜肉
小鲜肉 2020-12-31 09:09

After going through the docs, it seems there is no direct way to type check for min/max length of a string datatype.

But, is there a way to declare a string datatype

相关标签:
1条回答
  • 2020-12-31 09:59

    You can achieve this using a type constructor and something called a "Phantom Type" (read a nice article about this here) which is a technique to ensure that a type can not be assigned to a value directly.

    Here's an example of a StringOfLength<Min,Max> type using these techniques:

    type StringOfLength<Min, Max> = string & {
      __value__: never // this is the phantom type
    };
    
    // This is a type guard function which can be used to assert that a string
    // is of type StringOfLength<Min,Max>
    const isStringOfLength = <Min extends number, Max extends number>(
      str: string,
      min: Min,
      max: Max
    ): str is StringOfLength<Min, Max> => str.length >= min && str.length <= max;
    
    // type constructor function
    export const stringOfLength = <Min extends number, Max extends number>(
      input: unknown,
      min: Min,
      max: Max
    ): StringOfLength<Min, Max> => {
      if (typeof input !== "string") {
        throw new Error("invalid input");
      }
    
      if (!isStringOfLength(input, min, max)) {
        throw new Error("input is not between specified min and max");
      }
    
      return input; // the type of input here is now StringOfLength<Min,Max>
    };
    
    // Now we can use our type constructor function
    const myString = stringOfLength('hello', 1, 10) // myString has type StringOfLength<1,10>
    
    // the type constructor fails if the input is invalid
    stringOfLength('a', 5, 10) // Error: input is not between specified min and max
    
     // The phantom type prevents us from assigning StringOfLength manually like this:
    const a: StringOfLength<0, 10> = 'hello' // Type '"hello"' is not assignable to type { __value__: never }
    

    There are some limitations here - which are that you can't prevent someone from creating an invalid type like StringOfLength<-1, -300> but you can add runtime checks that the min and max values passed to the stringOfLength constructor function are valid.

    0 讨论(0)
提交回复
热议问题