如何实现支持递归类型推导的Typescript对象扩展强类型函数?
我差一点就完成了需求,相信有经验的Typescript开发者能很快解决这个问题。我想实现一个接收对象和可选扩展函数的函数,规则如下:
- 未传入参数时直接返回当前持有对象;
- 传入非undefined的extend函数时,返回绑定了更新后初始对象的新函数实例;
- 对象参数为可选,传入时会覆盖当前持有的对象值。
使用示例如下:
let f1 = func(undefined, {'x': 10}) f1() // {x:10} let f2 = func((pos: any) => ({...pos, y: 10}), {'x': 10}) //f2 => () => {x:number,y:number} let f3 = f2() //f3 is {x:10,y:10} f3 // {x:10,y:10} let f4 = f2((pos: any) => ({...pos, y: 10}),{}) f4() // {y:10}
JavaScript实现代码:
function func(extend?, obj?) { if (extend) { let newObj = extend(obj) return ((extend, obj = newObj) => func(extend, obj)) } else return obj }
目前JavaScript版本运行完全符合预期,我需要将其改造为Typescript版本,使其能正确推导返回对象的精准类型。
我的尝试
以下内容不属于问题本身,仅用于展示我已做的尝试:
我认为需要定义一个泛型类型,传入参数时返回新的泛型实例:
type Primitive = bigint | boolean | null | number | string | symbol | undefined; type PlainObject = Record<string, Primitive>; type genericFuncType<K extends PlainObject, Tin extends K=K, Tout extends Tin=Tin, T extends ((pos: Tin) => Tout) = undefined> = T extends undefined ? K: genericFuncType<Tout, Tout, Tout> let o = {x:10} type ot = typeof o to // {x: number} type t1 = genericFuncType<ot> t1 // {x: number} type t2 = genericFuncType<ot,ot,ot,(pos:ot)=>ot> t2 // a new function should be returned, but instead {x: number} is returned
我没能让这个泛型完全符合预期,再试下Typescript版func函数实现:
function func<K extends PlainObject, Tin extends K, Tout extends Tin, T extends ((pos: Tin) => Tout) = undefined>(extend: T, obj: K = {} as any): genericFuncType<K, Tin, Tout, T> { if (extend) { let newObj = extend(obj as any) return ((extend, obj = newObj) => func(extend, obj)) as any } else return obj as any } let f1 = func(undefined, {'x': 10}) //f1 => typeof f1 // {x:number} - good let f2 = func((pos: any) => ({...pos, y: 10}), {'x': 10}) //f2 => () => {x:number,y:number} typeof f2 // {x:number} - bad
请问我的实现哪里出错了?为什么无法递归返回带扩展类型的新函数?
内容的提问来源于stack exchange,提问作者Eliav Louski
相关产品推荐
相关产品推荐

