Typescript 缩小返回函数的类型';高阶函数的s参数

Typescript 缩小返回函数的类型';高阶函数的s参数,typescript,Typescript,我想这个标题并不能真正表达我在这里要做的事情。但我们还是走了 我有一个函数,它将返回另一个函数。问题是返回哪种类型的函数取决于我在第一个函数中输入的参数。像这样的东西 Function('function2')('what-ever-parameter-of-function2') Function('function3')('what-ever-parameter-of-function3') 我想做的是,当我点击第一个()时,它将自动完成'function2'或'function3'中的任

我想这个标题并不能真正表达我在这里要做的事情。但我们还是走了

我有一个函数,它将返回另一个函数。问题是返回哪种类型的函数取决于我在第一个函数中输入的参数。像这样的东西

Function('function2')('what-ever-parameter-of-function2')
Function('function3')('what-ever-parameter-of-function3')
我想做的是,当我点击第一个()时,它将自动完成'function2''function3'中的任何一个,在此基础上,当我点击第二个()时,它将根据在第一个()上选择的确切函数的参数自动完成

我的情况实际上比这复杂得多,但概念基本上是这样的

在这个例子中,我试图在第一个()中有property1或property2,并在第二个()中基于它(function1和function2)或(function3和function4)

注释掉的代码只是一个实验,我可以让它在property1或property2上自动完成,但在第二个()中没有自动完成的限制

你会在操场上看到一些错误,忽略最后一个,我只是懒得写一个实际实现的函数。我有两个问题

  • 在前2个错误中,它显示
  • 类型“突变[M][string]|突变[M][number]| 突变[M][symbol]”不可分配给类型“(…args:any)=> 任何

    我只是不明白为什么typescript将K视为
    string | number | symbol

  • 在此代码中

  • 如果您将鼠标悬停在K上,您将看到它有
    从不
    类型。我可以理解这一点,因为“property1”和“property2”中没有公共函数。但这对我来说毫无意义。我想要的只是在
    commit(name:'property1'|'property2')
    函数中,当我输入
    name
    参数时,它将
    name
    传递到下一个函数中,该函数将决定返回哪个set函数您的解决方案并不遥远

    您可以使用几个辅助提取器来正确排列所有内容,例如

    type ExtractParams=T扩展(a:推断K)=>any?K:从来没有
    类型ExtractReturn=T扩展(a:any)=>推断K?K:从来没有
    
    现在,您的
    Commit
    TestT
    类型变为

    类型突变={
    “财产1”:{
    f:(参数:字符串)=>void;
    g:(参数:字符串)=>字符串;
    },
    ‘物业2’:{
    h:(参数:编号)=>无效;
    j:(参数:数字)=>字符串;
    }
    }
    类型提交=
    (
    关键:K,
    有效载荷:提取参数

    )=>提取返回

    类型TestT={ 承诺:( 姓名:K )=>提交 }

    一切正常

    const a=test.commit('property1')(
    “f”,“你好”//好
    )//无效
    const b=test.commit('property2')(
    “h”,1//OK
    )//无效
    const c=test.commit('property2')(
    “j”,1//OK
    )//字符串
    

    太好了,我要把这个标记为正确答案。但是,如果我像这样向子函数添加第二个参数(因为我实际上想要第二个参数):f:(param:string,testparam:boolean)=>void;然后ExtractParams将永远不会返回,为了解决这个问题,我使用类型ExtractParams=T extends(b:any,a:inferk)=>any?K:从来没有
    const testO: TestT = {
          commit: function(name) {
            return (K, P) => 'void';
          }
        }