如何修复泛型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