Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 基于泛型的类型(函数参数的类型)_Typescript_Typescript Generics - Fatal编程技术网

Typescript 基于泛型的类型(函数参数的类型)

Typescript 基于泛型的类型(函数参数的类型),typescript,typescript-generics,Typescript,Typescript Generics,我想要一个基于函数参数类型的变量类型。我尝试使用泛型,但仍然有一些错误 接口A{ 值:字符串; } 接口B{ 值:数字; } 接口extA扩展了{ id?:字符串; } 接口extB扩展了extB{ id?:编号; } 函数foo(参数:T){ const newParam:T扩展了一个?extA:extB=param; newParam.id=param.value; 返回newParam; } 常数a={value:“1”}作为a; 常量b={value:1}作为b; const resul

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

接口A{
值:字符串;
}
接口B{
值:数字;
}
接口extA扩展了{
id?:字符串;
}
接口extB扩展了extB{
id?:编号;
}
函数foo(参数:T){
const newParam:T扩展了一个?extA:extB=param;
newParam.id=param.value;
返回newParam;
}
常数a={value:“1”}作为a;
常量b={value:1}作为b;
const resultA=foo(a);//结果是“extA”而不是“extA | extB”
const resultB=foo(b);//resultB是“extB”而不是“extA | extB”
代码是编出来的,但它显示了这个想法。根据函数参数
param
的类型,我想使用主要类型
newParam
中任一类型的扩展类型。因此,如果我为每种类型选择一个参数,TS将知道返回的是哪种类型。如何做到这一点


如果不需要泛型,则可以在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;
}

类型被正确检测

但是,您应该注意函数实现过程中的情况-您返回的
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