Upon observation, it is evident that the code provided in your example no longer generates an error after TypeScript 3.6. There was a bug reported regarding the improper behavior of excess property checking on deeply nested intersections, which has been resolved. You can find more details about this issue and its fix in microsoft/TypeScript#30715 and microsoft/TypeScript#32582.
If you are using versions of TypeScript prior to 3.6, a workaround will be necessary. One potential solution involves utilizing conditional and mapped types to traverse through object properties within nested intersection types and combine them into single objects. Essentially, transforming something like {a: string} & {b: number}
to {a: string; b: number}
.
One method to achieve this is by defining:
type MergeIntersections<T> =
T extends object ? { [K in keyof T]: MergeIntersections<T[K]> } : T;
This approach can then be applied to define UsedHere
:
type UsedHere =
MergeIntersections<{ someField: { anotherField: string } } & Abc>;
/* type UsedHere = {
someField: {
anotherField: string;
prohibited?: undefined;
};
} */
With this transformation, UsedHere
becomes a unified object type with each property being a single object type. The inclusion of prohibited?: undefined
serves the same purpose as prohibited?: never
, given that | undefined
is automatically appended to any optional properties when --strictNullChecks
is enabled.
Following these adjustments, the remaining code should compile without errors:
let x: UsedHere = {
someField: {
anotherField: ""
}
}; // okay
Hopefully, this information proves useful. Best wishes as you continue working with TypeScript, and may you eventually transition to a newer version!
Access Playground Link for Code Execution