Repository: TypeScript
Issue: Type mapping unexpectedly leads to missing keys
Labels: Bug,Help Wanted

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->

mapped types missing keys

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->

- I was unable to test this on prior versions because we didn't use the --exactOptionalPropertyTypes previously

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior

  The TypeScript Workbench can be used for more complex setups, try
  https://www.typescriptlang.org/dev/bug-workbench/

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->
[Playground link with relevant code](https://www.typescriptlang.org/play?exactOptionalPropertyTypes=true&ssl=29&ssc=52&pln=28&pc=65#code/C4TwDgpgBAYgNgQ2MCA7APAFQHxQLxQDeUA2gNJQCWqUA1hCAPYBmUmAugFxvntQC+AbgBQoSFADyYYJUaoEcMgwDOWXAWLkqNek1YduhflAgAPFKgAmyqAAVKAY1pYANFDK4A-O6jdUEADcIACcBEl0WNnYRMWgpGTkFW2DGSGCZCFUcfDtHZ0w3eNl5RRU1bBFRcGgAVSsIZmoIS2TUkNAlECz1IlIKajoGSIMoAFd6xv9LE3M0ax4yPm8KP0CQsIj9aKrxABEGppaUtI6y7I0+7UG9KO5xywOpmYt5zF4ob38g0O4KfnChltKrEoHUHpNmphGEVEnA1Dl4EgLOhCMIoOjLgMwY9mq0TiBOt12ABqTzcN6LYTGABkRDRGK0A32EKObXSBLO2C4C3YVIqwh20AAwnJvsB4QREcg0CjMTpAZJpMUksd2pRMmp2ABaMk8gT8wXaMCjYA5VEYqDBCAAW0YQT8o2tACN1gAfMYTQ4iC3WhD0ACyCCsSEYwRAutQjpdwW9GKtwAQ1AjUbdHvBXqpAoA9FmAKIAR1GChsItQYvQ1GNwGwhuoKGC1ualCQEAAkqgq2b6ejfQGg5YQ2GHc6QrH0fHE6hh9GoO77jjLCJ+Nms5hqlQbMRexBA8HgKGQNPR5aIAmk0fQnPPU9lw45MpTaZuNiWVCYSUK6h643LM2UO2qx6c0MW3XcB33IcoAABhcKlKhzOozEgBwUEscl10oTcBGEO9UAfKBD1Ba9IWhJVYXQUty0rE1sCA7soFA-tB0ImC4OEIA)

### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts
type Flatten<T> = { [K in keyof T]: T[K] };

type OptionalKeys<T> = { [K in keyof T]: {} extends Pick<T, K> ? K : never }[keyof T];
type OptionalProperties<T> = Pick<T, OptionalKeys<T>>;

type UndefinedPropertyKeys<T> = { [K in keyof T]: undefined extends T[K] ? K : never }[keyof T];
type DefinedPropertyKeys<T> = { [K in keyof T]: undefined extends T[K] ? never : K }[keyof T];

type UndefinedToOptional<T> = Flatten<{
    [K in UndefinedPropertyKeys<T>]+?: T[K]
} & {
    [K in DefinedPropertyKeys<T>]: T[K]
}>;

type Convert<T> = Flatten<{ [K in keyof OptionalProperties<T>]-?: T[K] }>;

type input = {
    remove: number | undefined;
    makeMandatory?: number;
    retain?: number | undefined;
}

//Equals Convert<input>
type intermediateInput = {
    makeMandatory: number;
    retain: number | undefined;
}

//Type is { makeMandatory: number; retain?: number | undefined }
const x: UndefinedToOptional<intermediateInput> = {
    makeMandatory: 0,
};

//Type is { }
const y: UndefinedToOptional<Convert<input>> = {
    makeMandatory: 0,
};
```

### 🙁 Actual behavior

The keys of the mapped type are stripped when applying another type mapping.

### 🙂 Expected behavior

The result of mapping a mapped type should show the same behaviour as mapping a recreation of the mapped type.