打字稿和类型推断:验证问题

时间:2021-01-14 06:46:07

标签: typescript types

我目前有一个功能与此类似(为了讨论,我编写了一个最小工作示例):

interface Variable {
  someMethod: () => void
}

const validateVariable(variable: Variable | undefined) {
  if(!variable) {
    throw new Error('Variable is undefined!')
  }
}

const doSomething = async (): void => { 
  // maybeGetSomething returns a Variable or undefined
  // depends on the database, so both cases are definitely possible
  const variable: (Variable | undefined) = await maybeGetSomething()

  validateVariable(variable)

  variable.someMethod()
}

但 Typescript 抱怨 variable 可能未定义。我不喜欢将 validateVariable 的代码放在 doSomething 中的想法,因为在我的情况下,验证是一个非平凡的函数,我需要能够重用。定义一个新变量只是为了让 Typescript 不抱怨它的类型也感觉很愚蠢,因为在验证之后它只能有 Variable 类型(代码不能通过带有 validateVariable(variable) 的行,除非它没有抛出,在这种情况下变量具有适当的类型)。

这样做的好方法是什么?我愿意改变我的代码结构,因为我仍然在学习很多关于 Typescript 的知识,我对此很灵活!

1 个答案:

答案 0 :(得分:1)

通过给 validateVariable 一个特殊的返回类型,你可以告诉打字稿如果函数返回(而不是抛出),那么变量必须被定义:

function validateVariable(variable: Variable | undefined): asserts variable is Variable {
  if(!variable) {
    throw new Error('Variable is undefined!')
  }
}

如果你这样做,那么在你调用 validateVariable(variable) 之后,variable 上的类型将被缩小到只有 Variable

Playground link