David F. B.
David F. B.

Reputation: 73

What is the meaning of something like `string[7]` in TypeScript?

While working in TypeScript today, I wanted to type a field to a string array with a set size. Though I know how to actually do this in TS, my C instincts made me write:

interface MyInterface {
  arrayField: string[7];
  // ...
}

I noticed that neither linter nor compiler complains about this, but it appears that arrayField is now simply typed to string. Does anyone know what's going on here?

Upvotes: 3

Views: 223

Answers (2)

Fixed length can be done easily:

interface MyInterface {
  arrayField: [string, string, string, string, string, string, string];
}

Well it is possible but for big integers it's pretty bad. You can write into dev tools simple code:

function array(length, type = "string") {
  return `[${Array(length).fill(type)}]`
}

Upvotes: 0

I believe it is a mistake. I think it should have been a string[].

While this notation string[7] is valid from TS perspective, it does not make any sense.

string is just a primitive type. Because all values are objects in javascript, string type has also a set of allowed methods/indexed properties.

In plain javascript "abs"[0] returns a. Since TypeScript does not have a char type, it should be compatible with javascript. Hence string[10000] returns just a string.

Here you can find all built in properties of string type:

type StringProperties= {
  [Prop in keyof string]: { key: Prop, value: string[Prop] }
}

enter image description here

How do we make a fixed length string in TS ?

Only with help of conditional types. You should iterate over each char and put this char into array. Then you need compare the length of the array with expected string length.

See example:


type ToArray<T extends string, Cache extends readonly string[] = []> =
  T extends ''
  ? Cache
  : T extends `${infer A}${infer Rest}`
  ? ToArray<Rest, [...Cache, A]>
  : Cache

type IsValid<T extends string[], Len extends number> = T['length'] extends Len ? true : false

type IsLength<T extends string, Len extends number> = IsValid<ToArray<T>, Len> // ok

type Result1 = IsLength<'hello', 6> // false
type Result2 = IsLength<'hello', 5> // true

Playground

If you are interested in string validation techniques, you can read my blog

Upvotes: 3

Related Questions