Adam Kettani Adam Kettani - 12 days ago 7
TypeScript Question

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

Answer

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.

Comments