【问题标题】:How to test for type in TypeScript/Angular?如何在 TypeScript/Angular 中测试类型?
【发布时间】:2020-09-23 18:36:58
【问题描述】:

我有一个函数可以返回 3 种可能类型中的 1 种:

getFoo(): Observable<Foo> | Promise<Foo> | Foo {

    //return 1 of 3 types

}

那么如何确保调用后的确切类型:

const foo = someClassObj.getFoo();

如果我现在想从 foo 获取数据,我怎么知道它是 Observable、Promise 还是类实例 Foo?当我尝试 instanceof 或 typeof 时,它们只检测到“对象”。

【问题讨论】:

  • 您可以只测试方法,.then.subscribe,参见例如stackoverflow.com/q/27746304/3001761。但重写它以使其更加一致可能更容易。
  • rxjs 导出一个您可以使用的方法isObservable() 。要检查它是否是一个承诺,请参考这个答案stackoverflow.com/a/27746373/6513723
  • "instanceof 或 typeof,它们只检测 'object'" 这些是 runtime 构造,它们对您的编译时静态类型一无所知,您也不能在编译时访问运行时值。
  • @JaredSmith 这一定是 TypeScript 的限制,因为大多数类型安全语言都有在运行时检查对象的类类型的方法。我假设这是因为 TypeScript 是 JS 的超集
  • @u84six 首先,如果您所说的类型安全是指“健全”,那么存在的“类型安全”语言很少,而且它们都没有在生产中广泛使用。至于静态类型语言,它们中的许多通常不会在运行时保留所有甚至任何类型信息:类型会被编译掉。即便如此,另一方面,编译器无法像您建议的那样知道您的值的运行时类型。

标签: javascript angular typescript


【解决方案1】:

你可以使用instanceof关键字。

const foo: any = someClassObj.getFoo();

if (foo instanceof Observable) {
} else if (foo instanceof Promise) {
} else if (foo instanceof Foo) {
}

【讨论】:

  • 如果 Foo 只是一个接口,最后一个是否也可以工作..?
  • 这对我不起作用。当函数返回 Observable 时,我可以在调试器中看到 foo instanceof Observable 返回 false。唯一解析为 true 的是“foo instanceof Object”。此外,我什至无法评估类对象 Foo,因为语法错误“Foo 仅指一种类型,但在此处用作值”
  • 对于Observable,可以在rxjs模块中使用isObservable函数
  • @Derek.W 好的,这行得通。这让我得到了 1/3 或那里的方式。我想为了保证,我可以查看 .then 是否已定义。所以这让我检查自定义的 Foo 类型。这意味着我必须添加类似类型保护的东西,我讨厌这样做
【解决方案2】:

好的,这就是我必须做的。感谢 Derek W,我能够在 rxjs 中使用 isObservable 函数。所以它让我想到了 isPromise,你不知道吗,Angular 8 有一个内置的实用程序函数。所以最终的代码是:

if(isObservable(foo)) {
   //handle observable
} else if(isPromise(foo)) {
   //handle promise
} else if(foo !== null) {
   //handle instance of Foo
} else {
   //handle null
}

【讨论】:

    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2015-12-07
    • 2022-10-18
    • 2018-10-01
    • 1970-01-01
    • 2021-02-23
    相关资源
    最近更新 更多