Rub*_*Jr. 5 javascript recursion typescript typescript-generics
我有一些 TypeScript 代码,我试图data-从元素属性的完整对象中提取属性。但是,我遇到了一个错误,“类型实例化过深并且可能是无限的。(2589)”。
我认为我的代码可能可以优化以修复此问题\xe2\x80\x94我可能会使它过于复杂\xe2\x80\x94所以我希望有专家的眼光来看看它是否可以提供帮助,或者我是否可以尝试去做太难了。
\n这是TS Repl的链接,我添加了以下代码:
\ntype AnyArray = any[];\ntype AnyArrayWithItems = [any, ...any];\ntype AnyFunction<Arguments extends any[] = any[]> = (...args: Arguments) => any;\n\n// The type of the first item in an array.\n// Input: `[1, 2, 3]`\n// Output: `1`\ntype Head<SomeArray extends AnyArray> = SomeArray extends AnyArrayWithItems\n ? SomeArray[0]\n : never;\n\n// The type of an array after removing the first element.\n// Input: `[1, 2, 3]`\n// Output: `[2, 3]`\ntype Tail<SomeArray extends AnyArray> = AnyFunction<SomeArray> extends (\n _: any,\n ...args: infer Remainder\n) => any\n ? Remainder\n : never;\n\nconst DATA_KEY_PREFIX = "data-" as const;\n\ntype DataKey = `${typeof DATA_KEY_PREFIX}${string}`;\n\ntype PrependIfDataKey<\n Key extends string | number | symbol,\n> = Key extends DataKey ? [Key] : [];\n\ntype DataKeys<\n Keys extends (string | number | symbol)[],\n> = Keys[\'length\'] extends 0 ? [] : [\n ...PrependIfDataKey<Head<Keys>>,\n ...DataKeys<Tail<Keys>>\n];\n\ntype DataProps<Props extends Record<string, unknown>> = Pick<\n Props,\n DataKeys<(keyof Props)[]>\n>;\n\nfunction getDataAttributes<Props extends Record<string, unknown>>(\n props: Props,\n): DataProps<Props> {\n return Object.keys(props)\n .filter((propName): propName is DataKey =>\n propName.startsWith(DATA_KEY_PREFIX),\n )\n .reduce(\n (dataProps, propName) => ({ ...dataProps, [propName]: props[propName] }),\n {} as DataProps<Props>,\n );\n}\n\n\nconst test = { href: "#", onClick: () => null, \'data-foo\': \'bar\' };\nconst attrs = getDataAttributes(test);\nRun Code Online (Sandbox Code Playgroud)\n
DataProps我认为最好退后一步,直接通过键重新映射来编写,而不是试图梳理递归类型以查看是否有办法让编译器更满意:
type DataProps<T> = { [K in keyof T as Extract<K, DataKey>]: T[K] };
Run Code Online (Sandbox Code Playgroud)
如果将键重新映射到 ,则键重新映射允许您省略属性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;
} */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3788 次 |
| 最近记录: |