For example, take this interface:
interface SomeObject {
prop1: number;
prop2: string;
prop3: {
innerProp1: number[];
innerProp2: string[];
innerProp3: {
deeperProp1: string[];
deeperprop2: boolean;
},
innerProp4: {
[key: string]: any;
},
innerProp5: {
[key: string]: any;
}
}
}
I want to create a type that accepts the shape of any object then returns the same object shape but with the provided type for the "leaf" properties and each property of the object can be optional. Something like the one below:
type ModifyShapeType<Shape, NewType> = ???
Such that when used against, for example, the interface above, I'd get type safety for the same object shape but with the provided type:
const myObject: ModifyShapeType<SomeObject, boolean> = {
prop1: true;
prop2: true;
prop3: {
// innerProp1: true;
// innerProp2: false;
innerProp3: {
deeperProp1: true;
// deeperprop2: true;
},
innerProp4: true,
// innerProp5: false
}
};
I've come up with the one below but I want to get rid of the original types from the shape and replace it with what I want and if possible, still retain the specificity on property reads and writes.
type ModifyShapeType<S, T> = Partial<Record<keyof S, Partial<S[keyof S] | T>>>;
Here's a TypeScript Playground.
Caveats currently:
- Types still being inferred from the original object type, in fact it's now all mixed.
- All properties now share the same type (specificity on read lost) which also means unsafe writes (specificity on write lost)
Is this even possible?