Typescript 如何通用地键入不一致函数的修改字典

Typescript 如何通用地键入不一致函数的修改字典,typescript,generics,Typescript,Generics,我有一个函数需要将具有部分动态属性的函数字典转换为具有类似属性的函数字典 到目前为止,我所拥有的: 接口字典{ [键:字符串]:T } 类型InputFunction=(值:T,参数?:any)=>T 类型InputFunctionMap=字典 类型OutputFunction=(参数?:any)=>void 类型OutputFunctionMap={ [P in keyof U]:输出函数 } 函数创建(键:字符串,值:T):[()=>T,(值:T)=>void] 函数创建(键:字符串,值:T

我有一个函数需要将具有部分动态属性的函数字典转换为具有类似属性的函数字典

到目前为止,我所拥有的:

接口字典{
[键:字符串]:T
}
类型InputFunction=(值:T,参数?:any)=>T
类型InputFunctionMap=字典
类型OutputFunction=(参数?:any)=>void
类型OutputFunctionMap={
[P in keyof U]:输出函数
}
函数创建(键:字符串,值:T):[()=>T,(值:T)=>void]
函数创建(键:字符串,值:T,输入:U):[()=>T,只读]
函数创建(键:字符串,值:T,输入?:U):[()=>T,(值:T)=>void]|[()=>T,只读]{
// ...
}
我正在努力实现的目标:

const[getFoo,updateFoo]=create('foo','foo')
getFoo()/=>“FOO”
updateFoo('foo')/=>'foo'
getFoo()/=>“foo”
接口数学参数{
运算:“乘”|“除”
操作数:数字
}
const[getBar,{addToBar,addSevenToBar,applyMathToBar}]=create('bar',0{
addToBar:(值,参数:编号)=>值+参数,
addSevenToBar:(值)=>值+7,
applyMathToBar:(值,参数:MathParameters)=>{
开关(参数、操作){
“乘法”情况:
返回值*参数。操作数
违约:
返回值
}
}
})
getBar()/=>0
addSevenToBar()
getBar()/=>7
addToBar(3)
getBar()/=>10
applyMathToBar({运算:'MULTIPLY',操作数:2})
getBar()/=>20
问题是,我不知道如何正确且通用地键入
参数
(我不希望它们是
任何
),以便可以从输入函数推断类型,并正确地作为输出函数中的参数使用

更新:

感谢您迄今为止的支持

我只是在让输出映射按预期工作时遇到问题:

type TailParams=T扩展(arg:any,…args:infera)=>void
? A.
:从不
常量输入=输入[名称为KEYU]
输出[name as keyof U]=(…参数:TailParams)=>{
//
}

抛出:
Type'(…args:TailParams)=>void'不可分配给类型“TailFunc”。

我可能会这样键入
create()

type TailFunc<T> = T extends (h: any, ...args: infer A) => infer R ? (...args: A) => R : never;

declare function create<T>(key: string, value: T): [() => T, (value: T) => void]
declare function create<T, U extends Record<keyof U, (value: T, ...args: any) => any>>(
    key: string,
    value: T,
    inputs: U
): [() => T, { [K in keyof U]: TailFunc<U[K]> }]
这些都不会在类型系统中给出错误,因此类型就是您想要的。我想,它在运行时的行为是否符合您的预期取决于
create()
的实现

好吧,希望这会有帮助;祝你好运



请注意,如何实现
create()
,以便所有类型检查都使用最少的类型断言,这超出了原始问题的范围,因此,我只发布了一个链接,指向一种可能的方法:

传递给
create
的函数没有任何类型分配给它们的参数,因此它们将
any
在输出函数中。如果我在输入函数参数中添加类型,
InputFunction
OutputFunction
类型不能将
参数定义为
any
。这
any
阻止了任何类型的推断可能性。我感谢您的帮助,但在测试您的解决方案时,我遇到了一个问题,输出函数没有按预期键入。请看我上面的更新。我上面的“代码链接”链接显示,
addToBar
已按预期键入
(参数:number)=>number
。因此,我无法重现您更新的错误。请尝试生成一个可以在没有外部依赖关系的独立IDE中演示您的问题的。是测试您的问题是否可重复的理想场所。祝你好运嗯,非常正确。最后一个问题,我不得不把操场链接放在问题中,因为它很长。非常感谢。我在回答的最后添加了一个可能的解决方案。一般来说,在函数实现中,要让未解析的条件类型进行类型检查并不容易;但这是一个与这个问题根本不同的问题,所以我不打算在这里详细讨论。祝你的代码好运!
getBar() 
addSevenToBar()
getBar() 
addToBar(3)
getBar() 
applyMathToBar({ operation: 'MULTIPLY', operand: 2 })
getBar()