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

时间:2019-07-28 19:43:41

标签: typescript type-inference typescript3.0 inferred-type

我不确定是否已经用不同的术语问了这个问题。我有一个带有两个参数的函数,其中两个都可以(独立地)为numberstringundefined。返回值被静态保证也是这两个参数之一:

export function wideNarrow(wide:number|string|undefined, 
                           narrow:number|string|undefined){
    return isNarrowScreen() ? narrow : wide;
}

在我的应用程序的某些部分中,我向函数传递了两个数字:

wideNarrow(8, 0);

但是,推断的返回类型为string|number,它显示数字运算错误:

const extendedAreaHeight = 26;
const baseY = extendedAreaHeight + wideNarrow(8, 0);

Operator '+' cannot be applied to types '26' and 'string | number'.ts(2365)

Object is possibly 'undefined'.ts(2532)

可以静态地推断出此特定调用将总是返回一个数字,为​​什么TypeScript无法检测到它并仍然认为可能会返回一个字符串或未定义,如何在不使用该字符串的情况下进行修复?破坏现有功能(例如,我可能返回undefinedstringstringnumberundefinednumber,以及其他任何组合我称之为函数的地方)?

我正在使用TypeScript 3.5.2 / Vscode 1.36.1。

2 个答案:

答案 0 :(得分:1)

正如托马斯(我同时发现)所建议的,具有两个具有相同签名的类型参数可以解决此问题:

export function wideNarrow
  <T=number|string|undefined,
   K=number|string|undefined> 
   (wide:T, narrow:K){
  return isNarrowScreen() ? narrow : wide;
}

使用两种确切类型而不是一种确切类型的原因是,正如我在问题中所述,它们可以不同。如果我只是将T设为K而将widenarrow都设为T,则将wide和{{1 }}具有相同的类型(例如,两个narrow),而我有时需要它们具有不同的类型(例如,宽的number但窄的string)。

注意:如果有人真的想知道在哪种情况下需要这种方式,我将使用它来填充我的React Native应用程序中的样式表,其中某些样式元素对{{1} } s (宽度为number的100个点)或number个(例如width: 100)用于水平填充一半的容器)。

答案 1 :(得分:0)

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

export function wideNarrow(wide:number, narrow:number): number;
export function wideNarrow(wide:number|string|undefined, narrow:number|string|undefined) {
    return isNarrowScreen() ? narrow : wide;
}