Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript Unions interface and primitive

Condidering this example

interface fooInterface {
    bar: any;
}
function(value: fooInterface | string) { 
    value.bar 
}

The error is: Property 'bar' does not exist on type '(fooInterface | string)'

I'm doing something wrong obviously. What I want to say basically is: value is EITHER an object implementing fooInterface or a string.

How can I do that?

Thank you

like image 518
Adam Kettani Avatar asked Oct 21 '25 13:10

Adam Kettani


1 Answers

You can't use value.bar because it's not definitely safe. It might be safe (because value might be a string), but the compiler doesn't know that for sure, and it won't let you do .bar unless it's sure. What you probably want to do is use a type guard:

if (typeof value !== "string") {
    value.bar
   // This compiles happily, because inside this if, value has
   // type 'fooInterface'. That's because TS now knows it isn't a string,
   // so *must* be a fooInterface.
}

You can play around with this in the typescript playground: notice that only one of the value.bar's fails, because it knows that only that one is wrong.

If you can't/don't want to do this you can instead just tell the compiler you know what you're doing with a type assertion (e.g. var definitelyFoo = <fooInterface> value), but a guard is usually the better choice.

like image 103
Tim Perry Avatar answered Oct 23 '25 07:10

Tim Perry