Questions tagged [mapped-types]

Use for questions about types for transforming other types, aka mapped types, in TypeScript, either custom or included in the standard library (like Omit, Partial, Pick, Readonly).

Use for questions about TypeScript's mapped types alongside the tag.


Mapped types are generic utility types allowing powerful type transformations while reducing code bloat, for example:

type Inverse<T extends (...args: any[]) => any> = (arg: ReturnType<T>) => Parameters<T>;

type pt = Inverse<(x: string) => number>; //(arg: number) => [x: string];

Mapped types can also modify type's properties via mapping modifiers like readonly (marks as immutable) and ? (marks as optional) prefixed with + (add mod) or - (remove mod) operation (+ is assumed if missing):

type MakeReadonly<T> = {
  readonly [ P in keyof T ] : T[P]
}

const r: MakeReadonly<{ a: 42 }> = { a : 42 };
r.a = 0; //Cannot assign to 'a' because it is a read-only property.

Users are free to define their own mapped types, but a set of the most common ones is included in the standard library. Among those are (many more are available, see the handbook):

Alias Role
Exclude<T, U> only members of T not assignable to U
Extract<T, U> only members of T assignable to U
Omit<T, K> type with properties whose keys are not of type K
Partial<T> all properties optional
Pick<T, K> type with properties whose keys are of type K
Readonly<T> all properties immutable
Record<K, T> type with keys of type K and values of T
Required<T> all properties required

v4.1 of TypeScript introduced key remapping that allows one to modify keys alongside values and optionally filter out properties if the as clause resolves to never:

type OnlyNumeric<T> = {
  [ P in keyof T as T[P] extends number ? P : never ] : T[P]
};

type num = OnlyNumeric<{ a: 1, b: "str", c: false }>; //{ a: 1 }

Useful Q&As:

  1. how to remove properties via mapped type in TypeScript
  2. Mapped Types: removing optional modifier
  3. How to convert a tuple type to a union?
168 questions
39
votes
4 answers

How to implement TypeScript deep partial mapped type not breaking array properties

Any ideas as to how might apply TypeScript's Partial mapped type to an interface recursively, at the same time not breaking any keys with array return types? The following approaches have not been sufficing: interface User { emailAddress:…
Allan Simoyi
  • 393
  • 1
  • 3
  • 8
23
votes
2 answers

In TypeScript, how to get the keys of an object type whose values are of a given type?

I've been trying to create a type that consists of the keys of type T whose values are strings. In pseudocode it would be keyof T where T[P] is a string. The only way I can think of doing this is in two steps: // a mapped type that filters out…
Aron
  • 6,128
  • 4
  • 24
  • 46
21
votes
4 answers

How to remove index signature using mapped types

Given an interface (from an existing .d.ts file that can't be changed): interface Foo { [key: string]: any; bar(): void; } Is there a way to use mapped types (or another method) to derive a new type without the index signature? i.e. it only has…
19
votes
2 answers

Difference between index signature and Record for empty object?

I cannot figure out the difference between index signatures and record types. Could someone explain the differences and when to use one versus the other? Specifically, I am looking to define the type of an object that will have random strings for…
mkusps
  • 250
  • 2
  • 7
18
votes
2 answers

how to remove properties via mapped type in TypeScript

Here is the code class A { x = 0; y = 0; visible = false; render() { } } type RemoveProperties = { readonly [P in keyof T]: T[P] extends Function ? T[P] : never//; }; var a = new A() as RemoveProperties a.visible…
Wander Wang
  • 211
  • 2
  • 5
15
votes
3 answers

Mapped Types: removing optional modifier

Given this code: interface Foo{ one?: string; two?: string; } type Foo2 = { [P in keyof Foo]: number; } I would expect the type of Foo2 to be { one: number; two: number; } However, instead it seems to keep the optional modifier { one?:…
NSjonas
  • 7,200
  • 5
  • 42
  • 78
15
votes
1 answer

How do I add an index signature for a mapped type?

Suppose I have interface interface X { a: string; b: number; c: boolean; } and a function function values(x: X) { return Object.keys(x).map(s => x[s]) } When I enable typescript's strict flag I get the error "Element implicitly has an…
Stuart
  • 197
  • 2
  • 9
9
votes
1 answer

Exclude object keys by their value type in TypeScript

I want to map an object type to a subtype that includes only keys whose values are of a specific type. For example, something like ExtractNumeric, where ExtractNumeric<{ str: string, num: number }> should be equivalent to the type: { num: number…
prmph
  • 4,827
  • 7
  • 31
  • 35
8
votes
2 answers

Typescript: index signatures in mapped type

How can I take the type { 'k': number, [s: string]: any } and abstract over 'k' and number? I would like to have a type alias T such that T<'k', number> gives the said type. Consider the following example: function f(x: { 'k': number, [s: string]:…
Andrey Tyukin
  • 38,712
  • 4
  • 38
  • 75
8
votes
1 answer

Do TypeScript conditional types map differently than constrained generics?

I am having no luck understanding why the code below functions as it does: type MapOverString = { [K in T]: K }; type IfStringMapOverIt = T extends string ? MapOverString : never; type ThisWorks = MapOverString<'a'>; // {…
evanbb
  • 83
  • 3
7
votes
5 answers

How to declare a "transposed" version of a type?

I would like to define a TS function to transpose an object to array for instance: const original = { value: [1, 2, 3], label: ["one", "two", "three"] } const transposed = [ {value: 1, label: "one"}, {value: 2, label: "two"}, …
Daniel Santos
  • 8,957
  • 15
  • 65
  • 139
6
votes
1 answer

How to convert a tuple type to a union?

How to map a tuple generic type to a union type? type NeededUnionType = T[keyof T]; // Includes all the Array properties values const value: NeededUnionType<[7, string]> = 2; // This should not be allowed (2 is the tuple length) Expected…
5
votes
0 answers

Mapped types in Scala similar to Typescript Pick, Exclude, etc

Following on the heels of Mapped types in Scala Is there a way to mimic Pick, Exclude, Diff and etc. from Typescript in Scala? Using the a similar example as above: case class Person(name: String, age: Int, address: String, phone: String) is there…
Anton
  • 2,034
  • 20
  • 39
5
votes
1 answer

How do I create a mapped type from the keys of a fixed object in Typescript

I have an object like this: const routes = { home: { path: '/', page: 'home' }, profile: { path: '/profile', page: 'users/profile' } } I would like to define a derived type from this, like so: type RouteName = keyof typeof routes, which creates…
majelbstoat
  • 10,765
  • 4
  • 26
  • 26
4
votes
1 answer

Get union type of recursive property in TypeScript

Suppose we have the interface: interface Node { children: C } Here, C is a generic that's a tuple that is the type of this node's children. Let's define some nodes: type Foo = Node<[]> type Bar = Node<[Foo, Foo]> type…
Splox
  • 547
  • 2
  • 11
1
2 3
11 12