I'm currently working on extracting data-
attributes from a complete object of element attributes using TypeScript code. However, I've encountered an error message stating "Type instantiation is excessively deep and possibly infinite (2589)."
It seems that my code might need optimization to resolve this issue—I suspect that it could be overly complex—so I would greatly appreciate guidance from an expert to determine if there's a solution or if the task I'm attempting is too challenging.
You can find the TypeScript Repl here, and I've shared the code below:
type AnyArray = any[];
type AnyArrayWithItems = [any, ...any];
type AnyFunction<Arguments extends any[] = any[]> = (...args: Arguments) => any;
// Define the type of the first item in an array.
type Head<SomeArray extends AnyArray> = SomeArray extends AnyArrayWithItems
? SomeArray[0]
: never;
// Define the type of an array after removing the first element.
type Tail<SomeArray extends AnyArray> = AnyFunction<SomeArray> extends (
_: any,
...args: infer Remainder
) => any
? Remainder
: never;
const DATA_KEY_PREFIX = "data-" as const;
type DataKey = `${typeof DATA_KEY_PREFIX}${string}`;
type PrependIfDataKey<
Key extends string | number | symbol,
> = Key extends DataKey ? [Key] : [];
type DataKeys<
Keys extends (string | number | symbol)[],
> = Keys['length'] extends 0 ? [] : [
...PrependIfDataKey<Head<Keys>>,
...DataKeys<Tail<Keys>>
];
type DataProps<Props extends Record<string, unknown>> = Pick<
Props,
DataKeys<(keyof Props)[]>
>;
function getDataAttributes<Props extends Record<string, unknown>>(
props: Props,
): DataProps<Props> {
return Object.keys(props)
.filter((propName): propName is DataKey =>
propName.startsWith(DATA_KEY_PREFIX),
)
.reduce(
(dataProps, propName) => ({ ...dataProps, [propName]: props[propName] }),
{} as DataProps<Props>,
);
}
const test = { href: "#", onClick: () => null, 'data-foo': 'bar' };
const attrs = getDataAttributes(test);