假设我想要一个包装另一个函数的函数,目的是稍微调整一下参数:
type WrappedFunction<P> = (props: P, children?: string[]) => void
type NonWrappedFunction<P> = (props: P, children: string[]) => void
const wrapFunction = <P>(rawFn: NonWrappedFunction<P>): WrappedFunction<P> => {
return (props, children) => rawFn(props, children ?? [])
}
然后,我可以将泛型函数传递给包装器函数,它也可以很好地工作:
const wrappedFunction = wrapFunction(<T>(props: {val: T}) => {})
// wrappedFunction is <T>(props: {val: T}, children?: string[]) => void , which is right
但是,如果我更改包装器函数的返回类型以添加不使用泛型参数P
的重载,则会出现编译错误:
// if I change WrappedFunction to this
type WrappedFunction<P> = ((props: P, children?: string[]) => void) & ((children?: string[]) => void)
// then I'll have TypeScript error about inability to infer props type here:
const wrappedFunction = wrapFunction(<T>(props: {val: T}) => {})
即使对于更简单的类型,它也是这样工作的;例如,将包装器定义更改为
const wrapFunction = <P>(rawFn: NonWrappedFunction<P>): void => {
将导致完全相同的错误.
因此,TypeScrip使用包装函数的返回类型来推断泛型参数.但是为什么呢?如何避免呢?
我试着内联字体,希望它可能太复杂了,打字在某一点上会引发推理.我还发现,如果非包装函数的参数仅为T
(而不是{val:T}
),则在该位置不会发生错误(但仍然不会推断类型).