For a project I’m working on, I required my objects to be defined with at leat one of the property from the object
for example
type DraggableOptions = {
identifier?: {
id?: string;
type?: string[];
};
modifiers?: {
highlight?: {
on: "dragmove" | "dragover";
class: string;
};
};
}
As all the properties are optional(because I also have default options) user can just pass a empty object {} when passing the DraggableOptions which I want to restrict to define at least one property from the object.
I also found a solution for this in the following stack overflow question but it does not work for nested objects which is my requirement. So based on the solution I have found I tried to write a recursive one also but could not get it right.
I found these two particular solution to be working in my case.
type AtLeastOne<T> = {
[K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
}[keyof T];
type AtLeastOne<T, U = { [K in keyof Required<T>]: Pick<Required<T>, K> }> = Partial<T> &
U[keyof U];
And I tried the following solution for recursive but they are not working
type RecursiveAtLeastOne<T> = {
[K in keyof T]: T[K] extends object ? AtLeastOne<T[K]> : T[K];
};
and
type RecursiveAtLeastOne<T> = {
[K in keyof T]: T[K] extends Record<string, any> ? AtLeastOne<T[K]> : T[K];
};
Can any please guide me what I’m doing wrong and what would be the right solution for this problem? Thank you so much in advance.
Btw as I am not able to write the recursive version correctly I’m using the following approach to make nested objects at least on required
export type DraggableOptions = AtLeastOne<{
identifier?: AtLeastOne<{
id?: string;
type?: string;
}>;
modifiers?: AtLeastOne<{
dropEffect?: "copy" | "move";
}>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data?: any;
}>;