Annotated solution
Published August 25, 2026The solution
type MyRequired<T> = { [K in keyof T]-?: T[K] }
The common wrong answer
type MyRequired<T> = { [K in keyof T]: T[K] }
This is the identity mapping, and that is the surprise: a mapped type over `keyof T` is *homomorphic*, so it copies the existing `?` and `readonly` modifiers across rather than dropping them. Optional properties stay optional, and the type is unchanged.
Line by line
-?The minus subtracts the modifier. It does two things at once: the key stops being optional, and `undefined` is removed from the value type — which is why `title?: string` becomes `title: string` and not `title: string | undefined`.
{ [K in keyof T]Mapping directly over `keyof T` is what makes this homomorphic, and homomorphic is what makes modifiers inheritable in the first place. Map over a computed key set instead and every modifier is lost by default.
Takeaway
`+` and `-` before `?` or `readonly` are the only way to change a property’s modifiers. Without them a mapped type quietly preserves whatever was already there, which makes "nothing happened" a very common bug.

