我有一些 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);
uj5u.com熱心網友回復:
與其試圖梳理你的遞回型別,看看是否有辦法讓編譯器更快樂,我認為最好退后一步,DataProps直接通過鍵重新映射來撰寫:
type DataProps<T> = { [K in keyof T as Extract<K, DataKey>]: T[K] };
如果您將鍵重新映射到never. 所以我使用的Extract<T, U>實用型僅保留鍵K可分配給DataKey。
這可以根據您的示例代碼的需要作業:
const test = { href: "#", onClick: () => null, 'data-foo': 'bar' };
const attrs = getDataAttributes(test);
type Attrs = typeof attrs;
/* type Attrs = {
"data-foo": string;
} */
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/405886.html
標籤:
