【问题标题】:Type based on generic (function parameter's type)基于泛型的类型(函数参数的类型)
【发布时间】:2020-07-04 22:59:34
【问题描述】:

我想要一个基于函数参数类型的变量类型。我尝试使用泛型,但仍然有一些错误。

interface A {
    value: string;
}

interface B {
    value: number;
}

interface extA extends A {
    id?: string;
}

interface extB extends B {
    id?: number;
}

function foo<T extends A | B>(param: T) {
    const newParam: T extends A ? extA : extB = param;

    newParam.id = param.value;

    return newParam;
}


const a = { value: "1" } as A;
const b = { value: 1 } as B;

const resultA = foo(a); // resultA is "extA" not "extA | extB"
const resultB = foo(b); // resultB is "extB" not "extA | extB"

代码是编造的,但它显示了这个想法。基于函数参数param 的类型,我想使用任一主要类型newParam 的扩展类型。因此,如果我选择每种类型之一的参数,TS 将知道返回的是哪种类型。如何做到这一点?

TS Playground

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    如果不需要泛型,那么可以在 TS 中使用函数重载:

    function foo(param: A): extA;
    function foo(param: B): extB;
    function foo(param: A | B): extA | extB {
        const newParam: extA | extB = param;
        newParam.id = param.value;
    
        return newParam;
    }
    

    Full playground

    类型被正确检测到。

    但是您应该在函数实现中注意自己 - 您返回 extA | extB 以前的重载可能无效(开发人员可能在实现中出错或添加新的重载而忘记实现)。
    示例:

    function foo(param: A): extA;
    function foo(param: B): extB;
    function foo(param: A | B): extA | extB {
        const newParam: extB = {
            value: 3,
            id: 22
        };
    
        return newParam; // always returned only `extB`
    }
    
    const a = { value: "1" } as A;
    const b = { value: 1 } as B;
    
    const resultA = foo(a);
    const resultB = foo(b);
    
    resultA.value // type detected as string
    // (correct according to overloading) but implementation
    // returns always number what is correct according to its definition
    // but incorrect according to previous overload signatures - developer mistake
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 2019-05-04
      • 2023-03-30
      • 2018-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多