如何修复泛型TypeScript函数以返回有效的推断类型?

如何修复泛型TypeScript函数以返回有效的推断类型?,typescript,typescript-generics,Typescript,Typescript Generics,我有以下类型脚本代码(): typemycallback=(s:string,payload:T)=>void; 接口接口{ do1:MyCallback; do2:MyCallback; [key:string]:(s:string,payload:any)=>void; } 函数convert void}>(callbackMap:T){ 常量结果:{[key:string]:(有效负载:U)=>void}={}; key(callbackMap).forEach(key=>{ if(cal

我有以下类型脚本代码():

typemycallback=(s:string,payload:T)=>void;
接口接口{
do1:MyCallback;
do2:MyCallback;
[key:string]:(s:string,payload:any)=>void;
}
函数convert void}>(callbackMap:T){
常量结果:{[key:string]:(有效负载:U)=>void}={};
key(callbackMap).forEach(key=>{
if(callbackMap[键]=“函数”的类型){
结果[key]=callbackMap[key].bind(null,“数据”);
}
})
返回结果;
}
常量映射=转换({
do1:(s:string,payload:number)=>{
//
},
do2(s:字符串,有效负载:字符串){
//
}
});
maps.do1(1);//有效的
maps.smth(“1”);//应该是类型检查错误,但TS认为它是有效的
我要做的是创建一个函数,它通过接口接受一个对象。该函数将对象中的所有方法转换为新对象,其中所有方法都有一个固定参数(通过
bind
method)。换句话说,我想转换这个接口

接口选项{
do1:(状态:字符串,有效负载:数字);
do2:(状态:字符串,有效负载:字符串);
.....
}

接口选项{
do1:(有效载荷:编号);
do2:(有效载荷:字符串);
....
}
我想让它成为泛型的,所以它可以基于泛型参数转换任何接口

我当前方法的问题是,我没有对我的
maps
对象进行任何智能感知和类型检查


是否可以修改我的
convert
函数,使传入接口自动推断返回类型?换句话说,我有完整的类型检查和返回值的智能感知(
maps

事实上,
maps.smth
是有效的,这是由于结果上有明确的索引签名。这里需要的是一个映射类型,用于将
IActions
的属性映射到包含修改过的方法的新类型。要创建新的方法签名,我们可以使用条件类型提取其余参数(跳过第一个)

typemycallback=(s:string,payload:T)=>void;
接口接口{
do1:MyCallback;
do2:MyCallback;
}
函数转换>(回调映射:T){
常量结果:记录任何>={}
key(callbackMap).forEach(key=>{
if(callbackMap的类型[key as keyof T]=“function”){
结果[key]=callbackMap[key as keyof T].bind(null,“data”);
}
})
返回结果为{
[P in keyof T]:T[P]扩展(s:string,…P:inferp)=>inferr?(…P:P)=>R:never;
};
}
常量映射=转换({
do1:(s:string,payload:number)=>{
//
},
do2(s:字符串,有效负载:字符串){
//
}
});
maps.do1(1);//有效的
地图。do1(“1”)//犯错误
maps.smth(“1”);//应该是类型检查错误,但TS认为它是有效的

哇,谢谢你!我也尝试过条件类型和
推断
,但最终没有找到可行的方法。这对我来说仍然很先进。你能建议如何解决你操场上的最后一个问题吗?TS投诉
在“Record void>类型上找不到带有“string”类型参数的索引签名。
哇。再次感谢你们,顺便说一句,感谢你们在TS领域所做的一切!今天我学到了很多关于TS的新东西:)。关于条件类型的非常有趣的视频。
type MyCallback<T> = (s: string, payload: T) => void;

interface IActions {
  do1: MyCallback<number>;
  do2: MyCallback<string>;
}

function convert<T extends Record<keyof T, (s: string, payload: any) => void>>(callbackMap: T) {

  const result: Record<string, (...a: any[]) => any> = {}

  Object.keys(callbackMap).forEach(key => {
    if (typeof callbackMap[key as keyof T] === 'function') {
      result[key] = callbackMap[key as keyof T].bind(null, "data");
    }
  })

  return result as {
    [P in keyof T]: T[P] extends (s: string, ...p: infer P) => infer R ? (...p: P) => R : never;
  };
}

const maps = convert<IActions>({
  do1: (s: string, payload: number) => {
    //
  },
  do2(s: string, payload: string) {
    //
  }
});

maps.do1(1); // valid
maps.do1("1"); //err
maps.smth("1"); // should be type-check error, but TS thinks it's valid