简体   繁体   English

如何处理`Type | typescript 和错误检查/测试中的布尔值返回值

[英]how to handle `Type | boolean` return values in typescript and error checking / tests

I have a function that can return a found object, or fail.我有一个 function 可以返回找到的 object,或者失败。 What's the best value to return in the failure case?在失败情况下返回的最佳值是多少? {}|null|undefined|false

The problem is my test rely on this object, but I get typescript warnings as false could also be returned问题是我的测试依赖于这个 object,但我收到 typescript 警告,因为也可以返回false

    const actualResult: ActionResult | boolean = await findAndRunAction(evt)
    if (actualResult) {
      expect(actualResult.klass).toBe('room')

where在哪里

function findAndRunAction(): ActionResult | false { 
// if found
return obj: ActionResult
// else
return false
 }

typescript is smart enough to know the value must be truthy but that should be when I am returning an instance of the full object, not just true . typescript 足够聪明,知道该值必须是truthy的,但这应该是当我返回完整 object 的实例时,而不仅仅是true

I could throw an error, or the other way would be to always return the same object type but just add a ok: true|false field into the object.我可能会抛出错误,或者另一种方法是始终返回相同的 object 类型,但只需在 object 中添加一个ok: true|false字段。 That seems a bit excessive, but I guess it does mean I always only have one return type...这似乎有点过分,但我想这确实意味着我总是只有一种返回类型......

Suggestions for good patterns to use with this in TS please!请推荐在 TS 中使用的好模式!

ts问题

未通过测试

The compiler fails, but the actual test is passing.编译器失败,但实际测试通过了。

Update: I did something like this:更新:我做了这样的事情:

// define all the other fields as optional

interface ActionResult {
  ok: boolean
  doc?: ActionData
  events?: string[]
  klass?: string
}

// so I can just return an empty obj in fail case

    return {
      ok: false
    }

I don't like this so much as it gives less rigidity on the actual type with all these options.我不太喜欢这个,因为它在所有这些选项中减少了实际类型的刚性。

There's a couple ways you could go about this, as you're using a union type with a primitive, the simplest solution would be to typeof check for the boolean eg有几种方法可以 go 关于这一点,因为您使用的是带有原语的联合类型,最简单的解决方案是对 boolean 进行typeof检查,例如

  if (typeof actualResult !== 'boolean') {

The compiler is smart enough to narrow down the options to the single ActionResult .编译器足够聪明,可以将选项缩小到单个ActionResult This works for primitives but only provides a shallow check so objects won't be properly differentiated.这适用于原语,但仅提供浅层检查,因此无法正确区分对象。

Additionally this is quite unwieldy if you have more than two return types as you have to exclude each and everyone one (and chaining else if won't continually narrow down the types left you'd have to nest them inside which will become a confusing else if hellscape), so a (still not perfect) option is to implement your own typeof check with generics and property checking.此外,如果您有两个以上的返回类型,这将非常笨拙,因为您必须排除每个人(并且链接else if不会不断缩小剩下的类型,您必须将它们嵌套在其中,这将变得令人困惑else if地狱景观),所以一个(仍然不完美)选项是使用 generics 和属性检查来实现您自己的 typeof 检查。

I got this snippet from how-to-use-typescript-type-guards and it's been handy a few times:我从how-to-use-typescript-type-guards得到了这个片段,它已经好几次了:

export const isOfType = <T>(
  varToBeChecked: any,
  propertyToCheckFor: keyof T,
): varToBeChecked is T =>
  (varToBeChecked as T)[propertyToCheckFor] !== undefined;

This little utility function will allow you to adjust your test to be:这个小实用程序 function 将允许您将测试调整为:

test('should test', () => {
  const actualResult = findAndRunAction(false);
  if (isOfType<ActionResult>(actualResult, 'klass')) {
    expect(actualResult.klass).toBe('room');
  }
});

This will compile, but it is not perfect.这将编译,但它并不完美。 We assume that klass is a unique property between the return types of your function, and it requires insight into the properties of the type you're checking for so its not a very abstracted solution, but might be helpful in some simple cases where the return is two differently structured objects.我们假设klass是 function 的返回类型之间的唯一属性,它需要深入了解您正在检查的类型的属性,因此它不是一个非常抽象的解决方案,但在返回的一些简单情况下可能会有所帮助是两个不同结构的对象。

In the case of something simple like this I'd probably just opt for the first option, but decide based on your needs:)在像这样简单的情况下,我可能只选择第一个选项,但根据您的需要决定:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM