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
的问题。