I'm using Typescript 3.2.2 and unable to achieve the most basic implementation of type guards:
interface Bird {
fly(): boolean;
}
interface Fish {
swim(): boolean;
}
function swimIfYouCan(x: Fish | Bird) {
if ((<Fish>x).swim) {
return true
}
}
This produces Error:(50, 11) TS2693: 'Fish' only refers to a type, but is being used as a value here.
in WebStorm and SyntaxError: /Users/sea-kent/git/docket-management/webapp/src/App.tsx: Unexpected token (51:8)
from yarn
. Is there a configuration needed to enable this syntax?
There are three different approaches possible that come to my mind for your problem.
If you want to cast it and directly use it you have to use the as
operator (as mentioned by @jonrsharpe in the comments), so for example (x as Fish).swim
use the in
operator to check if it is available, e.g. if ('swim' in x)
Last but not least (and for this case in my opinion the best case), simply do an instance of check to check what instance you've got: if (x instance of Fish)
Edit: Didn't read the question well enough, you can't check for interfaces in runtime. But there is no harm in creating a class on top of the interface
The recommended way to do pattern matching by checking the existence of a property is the in
operator:
interface Bird {
fly(): boolean;
}
interface Fish {
swim(): boolean;
}
function move(x: Fish | Bird) {
if ("swim" in x) {
return x.swim();
} else {
return x.fly();
}
}
By using the in
operator you can avoid the assertion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With