# Map Over Array Types In TypeScript

By [Florian Martens](https://pipe0.com/authors/florian-martens) · Published May 25, 2025

Source: https://pipe0.com/blog/map-over-arrays-typescript

> Learn how to create mapped types from array types in TypeScript



Most TypeScript developers have heard of [Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html).

A mapped type is a generic type that uses a union of property keys to create a new type:

```typescript
// turn any property into a boolean
type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};

type New = OptionsFlags<{a: string}> // {a: boolean}
```

This is similar to a [`for-in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) loop in JavaScript but uses types
instead of values. I recently had to do the same for an array-based type and struggled to find a way.

## Map over an array based type [#map-over-an-array-based-type]

Let's look at the following example of a tuple type.

<Callout title="Tip">
  Quick reminder: A tuple is a typed array with a pre-defined length and types for each index.

  ```typescript
  // define our tuple
  let ourTuple: [number, boolean, string];
  ```
</Callout>

```typescript
const ids = ["a", "b"] as const;

// We want to "loop" over each member of the tuple and create a type like this:
// [{name: "a"}, {name: "b"}] <- This is a type not a value
```

You can try to come up with a solution yourself if you are curious.

## Mapped types for arrays and tuples [#mapped-types-for-arrays-and-tuples]

Here is the solution for the previous problem.

```typescript
// this works
const ids = ["a", "b"] as const;
type MappedTuple<T extends readonly string[]> = {
  [P in keyof T]: T[P] extends string | number | symbol ? { name: T[P] } : never;
};

type Desired = MappedTuple<typeof ids>; // readonly [{name: "a"}, {name: "b"}]
```

In this solution, we use the same syntax we previously used for mapped types but apply it to
a tuple type.

### Why this works [#why-this-works]

Figuring out why this works can be confusing. The documentation for mapped types does not
mention arrays or tuples. So, why does this work?

### What we would expect [#what-we-would-expect]

In JavaScript, most things are objects. Arrays are objects, Maps are objects, Functions are objects, and so on.

If we use a mapped type on an array or tuple type we would expect all of the object properties like
`.length`, `0`, or `.toString` to be part of the mapping.

As we can see in the example above, this does not happen. We only get the tuple/array members.

### What actually happens [#what-actually-happens]

In [version 3.1](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-1.html#mapped-types-on-tuples-and-arrays)
TypeScript added support for mapped types for arrays and tuples.

Since then, mapped object types over tuples and arrays produce new tuples/arrays, rather than creating a new type where members
like `.push()`, `.pop()`, and `.length` are converted.

This applies to mapped types only. Creating a type from the object properties of a tuple or array
will still include all object properties like `.length`, `.map()`, etc.

```typescript
type Prettify<T> = {
	[K in keyof T]: T[K];
} & {};

const ids = ["a", "b"] as const;

type AllKeys = Prettify<keyof typeof ids>; // List all keys -> Not just members
```
