'Typescript generic constraint for type with only properties from another type
I'm trying to create a Overwrite type that can overwrite an existing type's properties with a different type. For instance:
type TypeA = { prop1: string; prop2: number };
type OverwrittenType = Overwrite<TypeA, { prop1: number; prop2: string }>;
// OverwrittenType is now equivalent to { prop1: number; prop2: string }
I found this SO answer which does the job nicely, however it's a bit too permissive for my liking, as it allows you to replace properties that were never in the original type to begin with.
type TypeA = { prop1: string; prop2: number };
type OverwrittenType = Overwrite<TypeA, { prop1: number; prop3: string }>;
// OverwrittenType is now equivalent to { prop1: number; prop2: number; prop3: string }
Below is the Overwrite type from that other thread.
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
How do I need to modify it to prohibit replacement keys that are not present in the initial type?
type TypeA = { prop1: string; prop2: number };
type OverwrittenType = Overwrite<TypeA, { prop1: number; prop3: string }>; // Throw some sort of error here, prop3 is not a key of TypeA
Solution 1:[1]
You can add a condition on you generic !
type Overwrite<T extends { [key in keyof U]: any }, U> = Omit<T, keyof U> & U;
type TypeA = { prop1: string; prop2: number };
type OverwrittenType = Overwrite<TypeA, { prop1: number }>; // ok
const foo: OverwrittenType = { prop1: 3, prop2: 3 }
type OverwrittenType2 = Overwrite<TypeA, { prop3: number }>; // error
const bar: OverwrittenType = { prop1: 3, prop3: 3 }
Solution 2:[2]
You could achieve this with a mapped type like this:
type TypeA = { prop1: string; prop2: number };
type Overwrite<T, U extends Partial<Record<keyof T, any>>> = { [Key in keyof T]: undefined extends U[Key] ? T[Key] : U[Key] };
type OverwrittenTypeWorks = Overwrite<TypeA, { prop2: string }>; // { prop1: string, prop2: string }
type WrongOverwrittenType = Overwrite<TypeA, { prop3: string }>; // Throw some sort of error here, prop3 is not a key of TypeA
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 | Guerric P |
