I'm looking for a solution to produce a mapped type that omit certain key base on the mapped key's value.
Concrete example:
I have an option: Options
struct, where Options
is an union type of shape:
{ type: DataType } or { type: DataType, params: DataParam }
Some elements of the union have params
key and some don't. I want to produce such union utilizing mapped type. Currently I have this working solution (Playground Link):
type DataParams = {
trade: never;
trade_bar: {
interval: number;
intervalUnit: "ms" | "s" | "m" | "ticks" | "vol";
};
};
type DataTypes = keyof DataParams;
type OptionsForDataType<T extends DataTypes> = {
type: T;
} & (DataParams[T] extends never
? {}
: {
params: DataParams[T];
})
type Options = {
[DataType in DataTypes]: OptionsForDataType<DataType>;
}[DataTypes];
But I'm not entirely satisfied with the ugly intersection + extends trick. Is there a better way to express such intention?
I was under the (probably wrong) impression that when { key: never }
, that key is effectively excluded from the struct, since nothing is subtype to never
, nothing can be assigned to that key. Turns out this is not the case, which looks strange to me.