构建函数参数中的“类型实例化太深,甚至可能是无限的”

时间:2019-11-24 03:07:18

标签: typescript

I created this function profound.(reggi/profound on github)它允许您传递函数对象。 profound返回一个函数。 profound使用此对象来生成实质上传递它们的所有输入参数。

似乎以重复方式使用它时,意味着profound中使用了多个profound。出现此灾难性错误:

  

类型实例化的深度过大,甚至可能是无限的

这是一个失败的例子:

export const example0 = profound({}, () => "anything")
export const example1 = profound({ example0 }, () => "anything")
export const example2 = profound({ example1 }, () => "anything")
export const example3 = profound({ example2 }, () => "anything")
export const example4 = profound({ example3 }, () => "anything")
export const example5 = profound({ example4 }, () => "anything")
export const example6 = profound({ example5 }, () => "anything")
export const example7 = profound({ example6 }, () => "anything")
export const example8 = profound({ example7 }, () => "anything")
export const example9 = profound({ example8 }, () => "anything")
export const example10 = profound({ example9 }, () => "anything")
export const example11 = profound({ example10 }, () => "anything")
export const example12 = profound({ example11 }, () => "anything")
export const example13 = profound({ example12 }, () => "anything")
export const example14 = profound({ example13 }, () => "anything")
export const example15 = profound({ example14 }, () => "anything")
export const example16 = profound({ example12, example13, example14, example15 }, () => "anything")
export const example17 = profound({ example16, example13, example14, example15 }, () => "anything")

我不确定这个概念是否注定要失败,或者我只是写得不好。

使用了三种主要的泛型,一种用于生成:

  1. 生成返回值
  2. 生成回调参数
  3. 将参数输入生成到返回的数组中。

我相信后者是导致问题的原因

namespace Params {
        type Func = (arg: any) => any
        type Funcs = { [k: string]: Func }
        type FirstArg<T extends any> =
            T extends [infer R, ...any[]] ? R :
            T extends [] ? undefined :
            T;
        type ThenArg<T> = T extends Promise<infer U> ? U : T
        type UnionToIntersectionValues<U, K extends keyof U = keyof U> =
            ([K] extends [never]
                ? unknown
                : K extends unknown
                ? (k: U[K]) => void
                : never
            ) extends (k: infer I) => void ? I : never
        type FnsNoArg<T extends Funcs> = UnionToIntersectionValues<ObjEmptyNever<ObjWithoutNever<{
            [K in keyof T]: Parameters<T[K]>[0] extends undefined ?
            { [KK in K]?: ThenArg<ReturnType<T[K]>> } :
            never
        }>>>
        type FnsHasArg<T extends Funcs> = UnionToIntersectionValues<ObjEmptyNever<ObjWithoutNever<{
            [K in keyof T]: Parameters<T[K]>[0] extends undefined ?
            never :
            { [KK in K]: ThenArg<ReturnType<T[K]>> } | FirstArg<Parameters<T[K]>>
        }>>>
        type Keys<T> = { [K in keyof T]: T[K] }[keyof T]
        type ObjEmptyNever<T> = Keys<T> extends never ? never : T
        type ObjKeysWithoutNever<T> = { [K in keyof T]: T[K] extends never ? never : K }[keyof T]
        type ObjWithoutNever<T> = Pick<T, ObjKeysWithoutNever<T>>;
        type ObjClean<T> = ObjEmptyNever<ObjWithoutNever<T>>
        type FnsOverride<T> = { [K in keyof T]: T[K] extends Func ? ThenArg<ReturnType<T[K]>> : never }
        type FnArguments<T> = ObjClean<{ [K in keyof T]: T[K] extends (arg: any) => any ? Parameters<T[K]>[0] extends undefined ? never : Parameters<T[K]>[0] : never }>
        export type Value<T extends Funcs> = FnArguments<T> extends never ? Partial<FnsOverride<T>> | void : FnsHasArg<T> | FnsNoArg<T>

}

所有这些都用于最后生成Value

我意识到这是一个巨大的类型,有很多条件。从逻辑角度来看,这是完全正常的。如何防止“类型实例化过深甚至可能无限大”的问题?我可以对此类型Value进行任何更改吗?

0 个答案:

没有答案