28

For example a string that can only be two characters long, which could be used for an ISO country code.

I have used Google and looked through the documentation but cannot find the answer.

user3336882
  • 3,083
  • 2
  • 15
  • 13

3 Answers3

20

There isn't a way to specify a string length as a type.

If you have a finite list of country codes, you could write a string literal type:

type CountryCode = 'US' | 'CN' | 'CA' | ...(lots of others);
Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
  • 2
    I thought about doing something like that, but using https://www.npmjs.com/package/country-data, but I decided against it because it would be overkill given the fact that the country codes will be returned from a backend API. I just want to ensure the variable cannot contain any obviously wrong data and thought it would be simple to specify length. I also thought about using an array but thought of that as somewhat convoluted plus you apparently cannot specify an enforced max length for an array (https://stackoverflow.com/questions/41139763/typescript-fixed-length-arraylength-type) – user3336882 Aug 15 '17 at 19:02
11

Actually it's possible to do

// tail-end recursive approach: returns the type itself to reuse stack of previous call
type LengthOfString<
  S extends string,
  Acc extends 0[] = []
> = S extends `${string}${infer $Rest}`
  ? LengthOfString<$Rest, [...Acc, 0]>
  : Acc["length"];

type IsStringOfLength<S extends string, Length extends number> = LengthOfString<S> extends Length ? true : false

type ValidExample = IsStringOfLength<'json', 4>
type InvalidExapmple = IsStringOfLength<'xml', 4> 

thanks to

vyenkv
  • 544
  • 7
  • 15
6

You can achieve this using a type constructor and a phantom type which are some interesting techniques to learn about. You can see my answer to a similar question here

cdimitroulas
  • 2,380
  • 1
  • 15
  • 22