Relevant GitHub issue: https://github.com/microsoft/TypeScript/issues/32562
- Extract the non matching props in a type, let's call it
NonMatching
- Extract the matching prop in a second type, say
Matching
- Intersect the two types using the
extends infer
technique
type TestType = {
a: SomeInterface;
b: string;
};
type Intersection<A, B> = A & B extends infer U
? { [P in keyof U]: U[P] }
: never;
type Matching<T, SomeInterface> = {
[K in keyof T]: T[K] extends SomeInterface ? K : never;
}[keyof T];
type NonMatching<T, SomeInterface> = {
[K in keyof T]: T[K] extends SomeInterface ? never : K;
}[keyof T];
type DesiredOutcome = Intersection<
Partial<Pick<TestType, Matching<TestType, SomeInterface>>>,
Required<Pick<TestType, NonMatching<TestType, SomeInterface>>
>
{[K in keyof T]: T[K] extends SomeInterface ? K : never }
it's kind of a workaround to map every matching key to it's own string literal type representation, i.e. given { a: never, b: SomeInterface }
you get { b: 'b' }
, then using indexed access types you get the matching properties in the form of union of string literal types