You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为柯里化函数接收的回调参数正确标注TypeScript类型

解决柯里化Props Getter工厂的类型标注问题

问题背景

我正在尝试创建一个柯里化的props getter工厂函数:外层函数接收defaultParams和propsConstructor回调,propsConstructor负责结合defaultParams和内层函数后续传入的新props,计算出最终的props对象。

当前遇到的问题是:调用内层函数时,传入的props参数以及返回的对象类型都被错误标注为AnyObject,无法准确推导实际类型。

原代码示例

// basic types
type EmptyObject = Record<string, never>
type AnyObject = Record<string, unknown>
type ObjectType = EmptyObject | AnyObject

export type PropsConstructor<
    DefParams extends AnyObject,
    Props extends AnyObject, // 后续嵌套函数调用时接收的参数
    ReturnObject extends AnyObject
> = (defaultParams: DefParams, props: Props) => ReturnObject

/**
 * @description input field props getter fabric
 * @returns props object that will be passed to input
 */
export const createPropsGetter = <
    DefParams extends AnyObject,
    ReturnObject extends AnyObject,
    Constr extends PropsConstructor<DefParams, AnyObject, ReturnObject>
>({
    defaultParams,
    propsConstructor,
}: {
    defaultParams: DefParams
    propsConstructor: Constr
}) => {
    return <NewProps extends AnyObject>(props: NewProps) => {
        return propsConstructor(defaultParams, props)
    }
}

const defaultParams = { one: 1, two: 2 }
type Props = { four: number }
type ReturnObject = typeof defaultParams & Props

const propsConstructor: PropsConstructor<
    typeof defaultParams,
    { four: 4 },
    ReturnObject
> = (defParams, props) => ({ ...defParams, ...props })

// 类型被推导为:<{ four: number }>(props: { four: number }) => AnyObject
const getter = createPropsGetter({
    defaultParams,
    propsConstructor,
})

const props = getter({ four: 4 }) 
props // 类型为AnyObject,不符合预期

解决方案

问题根源在于原代码中用AnyObject作为PropsConstructor的中间参数类型,导致TypeScript无法保留实际的类型信息。我们需要调整泛型参数的定义,让TS能准确推导内层函数的参数和返回值类型:

// basic types
type EmptyObject = Record<string, never>
type AnyObject = Record<string, unknown>
type ObjectType = EmptyObject | AnyObject

export type PropsConstructor<
    DefParams extends AnyObject,
    Props extends AnyObject,
    ReturnObject extends AnyObject
> = (defaultParams: DefParams, props: Props) => ReturnObject

/**
 * @description input field props getter fabric
 * @returns props object that will be passed to input
 */
export const createPropsGetter = <
    DefParams extends AnyObject,
    Props extends AnyObject,
    Return extends AnyObject
>({
    defaultParams,
    propsConstructor,
}: {
    defaultParams: DefParams
    propsConstructor: PropsConstructor<DefParams, Props, Return>
}) => {
    // 直接使用Props类型约束内层函数的参数,无需额外泛型
    return (props: Props): Return => {
        return propsConstructor(defaultParams, props)
    }
}

const defaultParams = { one: 1, two: 2 }
type Props = { four: number }
type ReturnObject = typeof defaultParams & Props

const propsConstructor: PropsConstructor<
    typeof defaultParams,
    Props,
    ReturnObject
> = (defParams, props) => ({ ...defParams, ...props })

// 类型正确推导:(props: Props) => ReturnObject
const getter = createPropsGetter({
    defaultParams,
    propsConstructor,
})

const props = getter({ four: 4 }) 
props // 类型为{ one: number; two: number; four: number },符合预期

关键调整说明

  • 将Props从Constr泛型的嵌套约束中抽离,作为createPropsGetter的独立泛型参数,让TypeScript能直接捕获内层函数需要接收的props类型
  • 移除多余的Constr泛型,直接用PropsConstructor<DefParams, Props, Return>约束propsConstructor参数,避免类型信息丢失
  • 内层函数不再声明新的NewProps泛型,直接复用Props类型,确保传入的参数与propsConstructor的要求一致,同时返回值类型也能准确推导为Return

内容的提问来源于stack exchange,提问作者Evgeniy Talko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:40:33