0

I have a function that can return 1 out of 3 possible types:

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

    //return 1 of 3 types

}

So how can I ensure the exact type after calling:

const foo = someClassObj.getFoo();

If I now want to get the data from foo, how can I know if it's Observable, Promise, or class instance Foo? When I try instanceof or typeof, they only detect 'object'.

8
  • 2
    You could just test for the methods, .then and .subscribe, see e.g. stackoverflow.com/q/27746304/3001761. But it might be easier to rewrite that to be more consistent. Commented Sep 23, 2020 at 18:43
  • 1
    rxjs exports a method isObservable() that you can use. For checking if it is a promise, refer to this answer stackoverflow.com/a/27746373/6513723 Commented Sep 23, 2020 at 18:44
  • 3
    "instanceof or typeof, they only detect 'object'" those are runtime constructs, they know nothing about your compile-time static types, nor can you access the runtime value at compile time. Commented Sep 23, 2020 at 18:47
  • @JaredSmith this is must be a limitation with TypeScript because mostly all type safe languages have a way to check objects for class type at runtime. I'm assuming it's because TypeScript is a superset of JS Commented Sep 23, 2020 at 22:09
  • @u84six first off if by type-safe you mean "sound" there are very few "type-safe" languages in existence and none of them are widely used in production. As for statically typed languages in general many of them do not retain all or even any type information at runtime: the types compile away. Even so, on the other side there's no way the compiler can know about the runtime type of your values like you are suggesting. Commented Sep 23, 2020 at 22:19

2 Answers 2

2

You can use instanceof keyword.

const foo: any = someClassObj.getFoo();

if (foo instanceof Observable) {
} else if (foo instanceof Promise) {
} else if (foo instanceof Foo) {
}
Sign up to request clarification or add additional context in comments.

6 Comments

Will the last one also work if Foo is just an interface..?
This does not work for me. I can see in the debugger when the function returns an Observable, foo instanceof Observable returns false. The only thing that resolves to true is 'foo instanceof Object'. Also, I can't even evaluate the class object Foo because of a syntax error 'Foo only refers to a type but is being used as a value here'
For Observable, you can use isObservable function in rxjs module
@Derek.W ok, that works. That gets me 1/3 or the way there. I suppose for promise, I can see if .then is defined. So that just leaves me with checking for the custom Foo type. This means I would have to add something like a type guard, which I hate doing
|
0

Ok, so this is what I had to do. Thanks to Derek W, I was able to use isObservable function in rxjs. So then it got me thinking about isPromise, and wouldn't you know, Angular 8 has a built-in utility function for that. So the final code is:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.