NSjonas
NSjonas

Reputation: 12032

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?: number; two?: number; }

Is it possible to remove the optional modifier when using mapped types?

Upvotes: 26

Views: 18030

Answers (4)

Digital Alpha
Digital Alpha

Reputation: 300

since typescript 2.8 You can basically use Required utility type

interface Foo{
  one?: string;
  two?: string;
}

type Foo2 = Required<Foo>

utilit types

in this case even if 'one' and 'two' are different types then you don't need to worry about that

Upvotes: 0

Jose Greinch
Jose Greinch

Reputation: 458

I would build my own Utility probably

interface Foo {
  one?: string;
  two?: string;
}

type RequiredWithType<T, V> = {
  [P in keyof T]-?: V;
}

// and then just use it
type Foo2 = RequiredWithType<Foo, Number>;

I've built a medium article here about mapped types that you mind find interesting :)

Upvotes: 2

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249536

In Typescript 2.8 you can explicitly eliminate the modifier:

type Foo2 = {
  [P in keyof Foo]-?: number;
}

Or use the Required type that is built into newer versions.

If you are using an older version you can use this workaround:

type Helper<T, TNames extends string> = { [P in TNames]: (T & { [name: string]: never })[P] };
type Foo3 = Helper<Foo, keyof Foo>;

Upvotes: 40

iarroyo
iarroyo

Reputation: 2444

You can use Required<T> as an alternative to -?

interface Foo {
  one?: string;
  two?: string;
}

type Foo2 = {
  [P in keyof Required<Foo>]: number;
};

Upvotes: 21

Related Questions