Consider the following code with lodash merge:
import { merge } from "lodash";
type Cfg = {
a: number
b: number
c: number
};
const cfg: Cfg = merge({ a: 1 }, { b: 2 }, { c: 4 });
This gives no error, because merge function preserves exact typings for all passed objects and resulting cfg is an intersection of all these types (type of cfg becomes a {a: number} & {b: number} & {c: number}, so it is compatible with Cfg ). If I pass to merge some property, that is not on Cfg, or miss some of the required properties, I will get an error.
But now, I need to do the same, but storing somewhere each of the objects beforehand.
Something like:
import { merge } from "lodash";
type Cfg = {
a: number
b: number
c: number
};
const arr: Partial<Cfg>[] = [];
function addPartial<ArgType extends Cfg>(partial: ArgType) { arr.push(partial); };
addPartial({ a: 1 });
addPartial({ b: 2 });
addPartial({ c: 3 });
const cfg: Cfg = merge(...arr);
Now by setting explicit type of array elements to Partial<Cfg>, I lose the exact type, so the resulting type that I get for cfg will be Partial<Cfg>, which of course does not satisfy Cfg.
Is there any way to gradually add up these partials, storing them without losing their type, so that it could be proved that cfg satisfies Cfg type?