Typescript 推断元组返回类型的类型脚本

Typescript 推断元组返回类型的类型脚本,typescript,typescript-generics,Typescript,Typescript Generics,我试图推断一个在TypeScript中返回元组类型的函数,但编译器总是推断该函数返回类型[未知,未知] type DoubleReturn<F> = F extends (...args: infer _) => [infer R1, infer R2] ? [R1, R2] : never; export function TransformMapKV<K, V, F extends (key: K, value: V) => DoubleRet

我试图推断一个在TypeScript中返回元组类型的函数,但编译器总是推断该函数返回类型
[未知,未知]

type DoubleReturn<F> = F extends (...args: infer _) => [infer R1, infer R2]
    ? [R1, R2]
    : never;

export function TransformMapKV<K, V, F extends (key: K, value: V) => DoubleReturn<F>>(
    values: ReadonlyMap<K, V>,
    callback: F
): Map<DoubleReturn<F>[0], DoubleReturn<F>[0]> {
    const newMap = new Map<DoubleReturn<F>[0], DoubleReturn<F>[0]>();

    for (const [k, v] of values) {
        const [nk, nv] = callback(k, v);
        // typeof nk is unknown
        // typeof nv is unknown
        newMap.set(nk, nv);
    }

    return newMap;
}
type DoubleReturn=F扩展(…参数:推断))=>[推断R1,推断R2]
? [R1,R2]
:从不;
导出函数TransformMapKV DoubleReturn>(
值:ReadonlyMap,
回拨:F
):地图{
const newMap=newMap();
for(常数[k,v]的值){
const[nk,nv]=回调(k,v);
//nk的类型未知
//nv的类型未知
newMap.set(nk,nv);
}
返回newMap;
}
还有一些测试代码:

// okay, x is [string, number]
type x = DoubleReturn<() => [string, number]>;

const m = new Map<string, string>();
m.set("abc", "123");
m.set("xyz", "789");

// okay, callback is (key: string, value: string) => [string, number]
const trM = TransformMapKV(m, (key, value): [string, number] => {
    return [key + "!", Number.parseInt(value)];
});

//好的,x是[字符串,数字]
类型x=DoubleReturn[字符串,数字]>;
常数m=新映射();
m、 集合(“abc”、“123”);
m、 集合(“xyz”、“789”);
//好的,回调是(key:string,value:string)=>[string,number]
const trM=TransformMapKV(m,(键,值):[字符串,数字]=>{
返回[键+“!”,Number.parseInt(值)];
});
编辑:简化了代码,但问题仍然存在


我不是Typescript类型推断专家,但我的直觉是,有一些推断循环-为了推断回调的类型,它需要知道类型参数F,它没有在TransformMapKV实例中指定,需要从参数推断,这同样需要TransformMapKV的确切类型

下面应该为您的案例提供技巧:

export function TransformMapKV<K, V, R1, R2>(
    values: ReadonlyMap<K, V>,
    callback: (key: K, value: V) => [R1, R2]
): Map<R1, R2> {
    const newMap = new Map<R1, R2>();

    for (const [k, v] of values) {
        newMap.set(...callback(k, v))
    }

    return newMap;
}
导出函数转换MAPKV(
值:ReadonlyMap,
回调:(键:K,值:V)=>[R1,R2]
):地图{
const newMap=newMap();
for(常数[k,v]的值){
set(…回调(k,v))
}
返回newMap;
}

这很简单,也很优雅,不知道为什么我没有想到。是的,我也经常被类型推断分心,继续写复杂的东西。关键的诀窍是出去散散步,重新思考