Typescript泛型与返回类型不兼容
我在typescript泛型方面遇到了一个问题:Typescript泛型与返回类型不兼容,typescript,generics,typescript-typings,typescript-generics,Typescript,Generics,Typescript Typings,Typescript Generics,我在typescript泛型方面遇到了一个问题: 函数isString(a:any):a是字符串{ 返回a的类型==='string' } 函数concat(a:T,b:T):T{ if(i字符串(a)和&i字符串(b)){ 返回a.concat(b) } 返回a+b } 这是一个功能%20%20%26%26%26%26%26%26%26%20%26%20%26%20%26%20%20%20%7%7%7%7%C%20%20%20%C%20%20%20%20%7%20%7%20%20%20%20
函数isString(a:any):a是字符串{
返回a的类型==='string'
}
函数concat(a:T,b:T):T{
if(i字符串(a)和&i字符串(b)){
返回a.concat(b)
}
返回a+b
}
这是一个功能%20%20%26%26%26%26%26%26%26%20%26%20%26%20%26%20%20%20%7%7%7%7%C%20%20%20%C%20%20%20%20%7%20%7%20%20%20%20%20%20%20%20%20%20%26%26%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%是2B%20b%0D%0A%7D%0D%0A
打字似乎合适,但我有一些错误。关于typescript泛型似乎有一些困惑,但我找到的答案没有一个对基本用例有帮助。typescript没有通过控制流缩小泛型类型(请参阅)。因此,即使已知
a
的类型为string
,T
的类型仍将顽固地保持T
。使代码按原样编译的唯一方法是使用安抚编译器(如注释中所述):
现在,这些示例的行为将与您预期的一样:
const oops1 = concat("a", "b"); // string
const oops2 = concat(5, 6); // number
let notSure = Math.random() < 0.5 ? "a" : 1
const oops3 = concat(notSure, 100); // error, notSure not allowed
const oops1=concat(“a”、“b”);//一串
常数oops2=concat(5,6);//数
让notSure=Math.random()<0.5?“a”:1
常量oops3=concat(不确定,100);//错误,不确定不允许
您可以使用泛型和,获得相同的行为,但这可能不值得:
type StringOrNumber<T extends string | number> =
[T] extends [string] ? string :
[T] extends [number] ? number : never
function concat<T extends string | number>(
a: T,
b: StringOrNumber<T>
): StringOrNumber<T> {
if (isString(a) && isString(b)) {
return a.concat(b) as any;
}
return (a as number) + (b as number) as any;
}
const oops1 = concat("a", "b"); // string
const oops2 = concat(5, 6); // number
let notSure = Math.random() < 0.5 ? "a" : 1
const oops3 = concat(notSure, 100); // error
输入StringOrNumber=
[T] 扩展[字符串]?字符串:
[T] 扩展[数字]?号码:从不
函数concat(
a:T,
b:StringOrNumber
):StringOrNumber{
if(i字符串(a)和&i字符串(b)){
返回a.concat(b)作为任何;
}
返回(a为数字)+(b为数字)如有;
}
常量oops1=concat(“a”、“b”);//一串
常数oops2=concat(5,6);//数
让notSure=Math.random()<0.5?“a”:1
常量oops3=concat(不确定,100);//错误
您缺少一个cast:将a.concat(b)返回为T
。还有:返回编号(a)+编号(b)作为T
function concat(a: string, b: string): string;
function concat(a: number, b: number): number;
function concat(a: string | number, b: string | number): string | number {
if (isString(a) && isString(b)) {
return a.concat(b);
}
return (a as number) + (b as number);
}
const oops1 = concat("a", "b"); // string
const oops2 = concat(5, 6); // number
let notSure = Math.random() < 0.5 ? "a" : 1
const oops3 = concat(notSure, 100); // error, notSure not allowed
type StringOrNumber<T extends string | number> =
[T] extends [string] ? string :
[T] extends [number] ? number : never
function concat<T extends string | number>(
a: T,
b: StringOrNumber<T>
): StringOrNumber<T> {
if (isString(a) && isString(b)) {
return a.concat(b) as any;
}
return (a as number) + (b as number) as any;
}
const oops1 = concat("a", "b"); // string
const oops2 = concat(5, 6); // number
let notSure = Math.random() < 0.5 ? "a" : 1
const oops3 = concat(notSure, 100); // error