'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?



Solution 1:[1]

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>;

Solution 2:[2]

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

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

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

Solution 3:[3]

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 :)

Solution 4:[4]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 iarroyo
Solution 3 Jose Greinch
Solution 4 Digital Alpha