There are 2 types
type A = {
x: number
y: number
}
type B = {
y: number
z: number
}
How to get type with common properties of that
Use static keyof
operator:
type Ka = keyof A // 'x' | 'y'
type Kb = keyof B // 'y' | 'z'
type Kc = Ka & Kb // 'y'
And define a Mapped Type with properties in Kc
:
type C = {
[K in keyof A & keyof B]: A[K] | B[K]
}
This defines a new type where each key will be present both in A
and B
.
Each value associated to this key will have type A[K] | B[K]
, in case A[K]
and B[K]
are different.
Use Conditional Type to map key to value only if type same in A and B:
type MappedC = {
[K in keyof A & keyof B]:
A[K] extends B[K] // Basic check for simplicity here.
? K // Value becomes same as key
: never // Or `never` if check did not pass
}
From this object, get union of all values, by accessing all keys:
// `never` will not appear in the union
type Kc = MappedC[keyof A & keyof B]
Finally:
type C = {
[K in Kc]: A[K]
}
Based on @kube's answer, you could use generics to create a reusable type:
type Common<A, B> = {
[P in keyof A & keyof B]: A[P] | B[P];
}
This allows you to create intersections on the fly:
const c: Common<T1, T2> = { y: 123 };
Based on @kube's answer,
type Common<A, B> = Pick<
A,
{
[K in keyof A & keyof B]: A[K] extends B[K]
? B[K] extends A[K]
? K
: never
: never;
}[keyof A & keyof B]
>;