Type of connection: one or the other. Not sure if it's design or bug

Consider a situation where an object can have only those FooBar or Baz interfaces that are listed below.

 interface FooBar { foo: string; bar: string; } interface Baz { baz: string; } 

I understand that this “one or another” situation can be solved by creating a union between FooBar and Baz .

 type FooBarOrBaz = FooBar | Baz; 

So far so good ...

The problem I am facing is that the following object passes type checking:

 const x: FooBarOrBaz = { foo: 'foo', baz: 'foo', }; 

This is mistake?

Playground Example

Thanks in advance!

+5
source share
1 answer

I think there is a mistake here.

This can be made even more explicit by switching to classes, and then using the narrowing aspects of instanceof type in union types.

Start with the code, but switch to the classes:

 class FooBar { foo: string; bar: string; } class Baz { baz: string; } type FooBarOrBaz = FooBar | Baz; 

Create an instance like you - it compiles fine.

 const x: FooBarOrBaz = { foo: 'foo', baz: 'baz', } 

Check if we have a FooBar :

 if (x instanceof FooBar) { console.log("x is a FooBar : (" + x.foo + "," + x.bar + ")"); } else { console.log("x is not FooBar must be Baz : " + x.baz); } 

This compiles without warning or fingerprints x is not FooBar must be Baz : baz .

Check if we have a Baz :

 if (x instanceof Baz) { console.log("x is a Baz : (" + x.baz + ")"); } else { console.log("x is not Baz must be FooBar : " + x.foo + "," + x.bar); } 

Also compiles fine, but prints x is not Baz must be FooBar : foo,undefined

Thus, either accepting this type of input is an error, or it can lead to an error in narrowing the type of protection device of type instanceof .

+2
source

Source: https://habr.com/ru/post/1264861/


All Articles