【问题标题】:TypeScript inferring tuple return typesTypeScript 推断元组返回类型
【发布时间】:2020-06-24 21:29:50
【问题描述】:

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

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;
}

还有一些测试代码:

// 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)];
});

编辑:简化了代码,但问题仍然存在。

playground link

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    我不是 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;
    }
    

    【讨论】:

    • 这样简单多了,也优雅多了,不知道为什么我没有想到。
    • 是的,我也经常被类型推断分心,继续写复杂的东西。关键的诀窍是去散步并重新思考。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 2019-09-03
    相关资源
    最近更新 更多