Yohohodev

How to get the type of an array in TypeScript

#TypeScript

Table of Contents

Problem

Let's say we have an array of cars and a function that returns the name of a car:

const cars = ['BMW', 'Audi', 'Porse'];

const getCar = (name: string) => {
  return cars.find((car) => car === name);
};

console.log(getCar('Audi')); // Audi
console.log(getCar('string')); // Returns undefined without an error

In the function, we specified string as the type for the name argument, allowing us to pass any string as an argument. But what if we want to allow only the names of cars present in the cars array and highlight an error immediately before the code is executed?

Enumerated Type for Restricting Values

Certainly, we can create a separate type with an enumeration of all values from the array and use it as the type for name, for example:

type Car = 'BMW' | 'Audi' | 'Porse';

const getCar = (name: Car) => {
  return cars.find((car) => car === name);
};

// Error: Argument of type '"string"' is not assignable to parameter of type '"BMW" | "Audi" | "Porse"'
console.log(getCar('string'));

But in this case, we would need to manually update the type whenever there are changes to the array.

Using const assertions

Therefore, it's worth using const assertion in combination with the typeof operator.

const cars = ['BMW', 'Audi', 'Porse'] as const; // readonly ['BMW', 'Audi', 'Porse'] instead of string[]
type Car = (typeof cars)[number]; // 'BMW' | 'Audi' | 'Porse'

const getCar = (name: Car) => {
  return cars.find((car) => car === name);
};

as const refines the type of cars and creates a readonly tuple that is immutable (TypeScript will throw an error if we attempt to modify it). Then, we extract all possible values from the array using typeof cars[number].

More details about const assertions can be found in the official TypeScript documentation.