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_Type Inference_Typescript3.0_Inferred Type - Fatal编程技术网

TypeScript从使用的参数推断返回类型

TypeScript从使用的参数推断返回类型,typescript,type-inference,typescript3.0,inferred-type,Typescript,Type Inference,Typescript3.0,Inferred Type,我不确定是否有人用不同的术语问过这个问题。我有一个接受两个参数的函数,其中两个参数都可以(独立地)是数字,字符串,或者未定义。静态地保证返回值也是这两个参数之一: export function wideNarrow(wide:number|string|undefined, narrow:number|string|undefined){ return isNarrowScreen() ? narrow : wide; } 在我

我不确定是否有人用不同的术语问过这个问题。我有一个接受两个参数的函数,其中两个参数都可以(独立地)是
数字
字符串
,或者
未定义
。静态地保证返回值也是这两个参数之一:

export function wideNarrow(wide:number|string|undefined, 
                           narrow:number|string|undefined){
    return isNarrowScreen() ? narrow : wide;
}
在我的应用程序的某些部分,我将两个数字传递给函数:

widearrow(8,0)

但是,推断的返回类型是
string | number
,它显示了数字操作的错误:

const extendedAreaHeight = 26;
const baseY = extendedAreaHeight + wideNarrow(8, 0);
运算符“+”不能应用于类型“26”和“string | number”.ts(2365)

对象可能是“未定义的”。ts(2532)

可以静态地推断,这个特定的调用将始终返回一个数字,为什么TypeScript没有检测到它,并且仍然认为可能会返回一个字符串或未定义的字符串,以及如何在不破坏现有功能的情况下修复它(例如,我可以返回
未定义的
字符串
字符串
数字
未定义的
数字
,以及我调用该函数的其他位置中这些的任意组合)


我使用的是TypeScript 3.5.2/Vscode 1.36.1。

您可以添加更精确的函数声明,如下所示:

导出函数加宽箭头(宽:数字,窄:数字):数字;
导出函数WideArrow(宽:数字|字符串|未定义,窄:数字|字符串|未定义){
返回IS窄屏()?窄:宽;
}
该函数仍然只有一个实现,但有多个声明,这有助于编译器。请参阅文档部分。

正如Thomas建议的(我同时发现的),使用两个具有相同签名的类型参数可以解决问题:

export function wideNarrow
  <T=number|string|undefined,
   K=number|string|undefined> 
   (wide:T, narrow:K){
  return isNarrowScreen() ? narrow : wide;
}
导出功能箭头
(宽:T,窄:K){
返回IS窄屏()?窄:宽;
}
有两个确切类型而不是一个的原因是,正如我在问题中所说的,它们可以不同。如果我只将
T
而不使用
K
,并将
类型设置为
T
,则会强制
为同一类型(例如,两者都是
number
s),而我有时需要它们的类型不同(例如宽
string
但窄
number


注意:如果有人真的想知道我在什么情况下需要它,我会用它来填充React原生应用程序中的样式表,其中一些样式元素对
number
s非常满意,例如(
width:100
100点宽)或
string
s(例如
width:'50%
)用于水平填充容器的一半。)

我不知道为什么不能这样推断,但如果将其定义为泛型:
函数wideArrow(宽:t,窄:t){…}
@Thomas这对我来说似乎是一个答案,为什么不做一个呢。@Thomas不,那不行。它要求两个参数的类型相同,这不包括我的用例。我需要能够将其与字符串和数字一起使用,例如
WideArrow(25,'20%”)
那么TS将无法推断正确的类型。它不会深入代码。即使我
返回true?窄:宽;
类型脚本不会由此推断返回的类型将始终是
typeof窄
;返回类型仍然是联合类型
typeof窄| typeof宽将泛型与两种类型一起使用
函数wideArrow(宽:T,窄:U){…}
,但当将函数与字符串和数字一起使用时,仍然存在返回类型为
string | number
的问题。