Suppose that I have two interfaces:
interface Box {
x: number
y: number
}
and
interface ColouredBox {
x: number
y: number
colour: string
}
Assume for the purpose of this question, that I cannot change the interfaces.
Now when constructing objects, I have code like this:
let a: Box|ColouredBox = {x: 1, y: 2}
if( something ){
a.colour = "Blue" // Compilation Error
}
I get this error on a.colour = "Blue"
:
Error:(24, 26) TS2339: Property 'colour' does not exist on type 'Box'.
Why? Is this a limitation of the TS compiler? Other than completely reconstructing the object, is there a different workflow that I could use?
Using a Partial
Instead of using a union type, you can try using a Partial
let a: Partial<ColouredBox> = {x: 1, y: 2}
The partial will set all the properties of the ColoredBox
as optional.
Live example here.
Update:
Eliminate an Interface
If you only want the color part of the interface to be optional, you can eliminate one of the interfaces.
interface Box {
x: number;
y: number;
color?: string;
}
Then to determine if you're dealing with a colored box:
if (box.color) { ... }
Type Assertion
If you stick to using both interfaces, you can specifically treat a
as a ColouredBox
using the as
keyword (a.k.a. a Type Assertion).
let a: Box | ColouredBox = { x: 1, y: 2 };
(a as ColouredBox).colour = "Blue";