Reputation: 2314
I have the following type:
selection: (InterfaceX | InterfaceY)[]
interface InterfaceX {
switch: boolean
propertyOne: number
}
interface InterfaceY {
switch: boolean
propertyTwo: number
}
Selection can be:
{switch: true, propertyOne: 1} or {switch: false, propertyTwo: 2}
Which causes the following type errors in a ternary:
selection.switch ? selection.propertyOne : selection.propertyTwo
TS2339: Property 'propertyOne' does not exist on type 'InterfaceY'.
As well as
TS2339: Property 'propertyTwo' does not exist on type 'InterfaceX'.
Is there a way to declare which side of the ternary is using which type? So if switch is true it is InterfaceX
otherwise its InterfaceY
? I do not want to add any properties to my interfaces. Thanks!
New example:
import React from "react";
export interface Props {
items: (InterfaceX | InterfaceY)[];
}
interface InterfaceX {
toggle: true;
sharedProp: string;
propertyX: string;
}
interface InterfaceY {
toggle: false;
sharedProp: string;
propertyY: string;
}
export const Picks = (props: Props) => {
const { items } = props;
return items.map(item =>
item.toggle ? (
<div>
{item.sharedProp} {item.propertyX} // Unresolved variable propertyX
</div>
) : (
<div>
{item.sharedProp} {item.propertyY} // Unresolved variable propertyY
</div>
)
);
};
Upvotes: 0
Views: 1471
Reputation: 5650
Based on your example you'll want the switch
property to be the exact value (not boolean
) so that TypeScript can properly discriminate between the two types. Otherwise, since they can both be false
and true
there's no way to determine which type it is.
For example:
interface InterfaceX {
switch: true;
propertyOne: number;
}
interface InterfaceY {
switch: false;
propertyTwo: number;
}
// Example of using a ternary
const fn1 = (selection: InterfaceX | InterfaceY) => {
selection.switch ? selection.propertyOne : selection.propertyTwo
}
// Example of using a swtich
const fn2 = (selection: InterfaceX | InterfaceY) => {
switch (selection.switch) {
case true:
return selection.propertyOne;
case false:
return selection.propertyTwo
}
}
Upvotes: 2