I have this minimal example:
type A = {
children: any;
size?: string;
};
type B = Omit<A, 'children'>;
// The type of B makes sense to me.
type Y = {
[x: string]: any;
children: any;
size?: string;
};
type Z = Omit<Y, 'children'>;
// Why is the type of `size` lost in Z?
(You can check it in this playground.)
Is this a bug?
Explanation
When you hover Omit<Y, 'children'>
, you see this definition.
You can understand that it relies on Exclude<keyof Y, 'children'>
.
This means that the keys in your object are processed independently from their associated type. Since you are using a generic index ([x: string]
), the keys get merged when calling keyof
because size
is a part of [x: string]
.
I have added some info from your playground in this one
I wouldn’t say it’s a bug, but it sure seems like a tricky pitfall.
Solution
A workaround to this issue would be to use the following type definition:
type A = {
children: any;
size?: string;
};
type Solution = { [x: string]: any } & Omit<A, 'children'>
const obj: Solution = {};
obj.size;
// obj.size is of type string | undefined