【发布时间】:2022-01-05 09:29:49
【问题描述】:
我有一些 TypeScript 代码,我试图从元素属性的完整对象中提取 data- 属性。但是,我遇到了一个错误,“类型实例化过深并且可能是无限的。(2589)”。
我认为我的代码可能会被优化来解决这个问题——我可能过于复杂了——所以我很感激专家的眼睛看看它是否可以帮助,或者如果我是什么努力去做太难了。
这是TS Repl 的链接,我已将以下代码包含在内:
type AnyArray = any[];
type AnyArrayWithItems = [any, ...any];
type AnyFunction<Arguments extends any[] = any[]> = (...args: Arguments) => any;
// The type of the first item in an array.
// Input: `[1, 2, 3]`
// Output: `1`
type Head<SomeArray extends AnyArray> = SomeArray extends AnyArrayWithItems
? SomeArray[0]
: never;
// The type of an array after removing the first element.
// Input: `[1, 2, 3]`
// Output: `[2, 3]`
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);
【问题讨论】:
标签: javascript typescript recursion typescript-generics