I want to understand how an intersection works when it’s necessary to use Partial
. This is used for setStatePartialHook
when the exact type for the state is unknown.
type ModorkParams = {
clientSessionId: string;
};
type Config<T extends Record<string, string>> = ModorkParams & Omit<T,'clientSessionId'>;
const foo = <T extends Record<string, string> = {}>() => {
let t: Partial<Config<T>> = { clientSessionId: "fdfdf" }; // Type '{ clientSessionId: "fdfdf"; }' is not assignable to type 'Partial<Config<T>>'.(2322)
console.log(t);
};
Why doesn't Partial
take Omit into account?
type ModorkParams = {
clientSessionId: string;
};
type Config<T extends {
clientSessionId?: string;
}> = ModorkParams & T;
Give the same error.
You can't omit a literal type from its generic type, like you cannot do Exclude<string, 'clientSessionId'>
, it would give string
anyway, so your omitting Record<string,string>
doesn't work but TS tries to do some work and infers T
in the initialization as Omit<T, 'clientSessionId'>
which is rejected due presence of clientSessionId
in the object literal. Overall the whole construct seems overcomplicated given the absence of the whole life-cycle of t
variable and redundant typing in the variable's initialization.
A simpler alternative would be
type ModorkParams = {
clientSessionId: string;
};
type Config = ModorkParams & Record<string, string>;
const foo = () => {
let t: Config = { clientSessionId: 'asdf' };
console.log(t);
};