Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining multiple mapped types in typescript?

Say I have the following typescript code:

type fruit = "apple" | "banana" | "pear"
type color = "red" | "yellow" | "green"

And I want to create a type that has a numeric property for each fruit and a boolean property for each color, something like

type FruitsAndColors = {
  [key in fruit]: number;
  [key in color]: boolean
}

Unfortunately, this errors with the message "A mapped type may not declare properties or methods", yet it compiles fine. What's actually happening here?

I can get around this with something like

type FruitsAndColors = {
  [key in fruit]: number;
} & {
  [key in color]: boolean
}

But I'd like to know what the actual issue is.

like image 369
emanresu A Avatar asked Mar 09 '26 19:03

emanresu A


2 Answers

It's not "vscode's typescript extension," it's TypeScript. It doesn't let you do two mappings in a single type construct. It's just the syntax of the construct doesn't allow it.

Instead, you do what you showed:

type FruitsAndColors = {
    [key in fruit]: number;
} & {
    [key in color]: boolean
};

Note, though, that that type requires all six properties to be present in the object. Maybe that's what you want, but if not, add ? after the mapped keys (or wrap the entire thing in Partial<>):

type FruitsAndColors = {
    [key in fruit]?: number;
} & {
    [key in color]?: boolean
};
// Or
type FruitsAndColors = Partial<{
    [key in fruit]: number;
} & {
    [key in color]: boolean
}>;

Playground for the above

like image 52
T.J. Crowder Avatar answered Mar 11 '26 08:03

T.J. Crowder


You can also use conditional types:

type FruitsAndColors = Partial<{
  [Key in (Fruit | Color)]: Key extends Fruit ? number : Key extends Color ? boolean : never;
}>

Playground

like image 24
Ramesh Reddy Avatar answered Mar 11 '26 07:03

Ramesh Reddy