When working with code that involves creating and using an Entry, it's important to consider two perspectives. One perspective focuses on the code responsible for generating an Entry, while the other deals with the code that utilizes the Entry. This approach allows for flexibility when creating an Entry, as it can be either a banana or an apple, providing more options in the process.
However, in the case of code that uses the Entry, there is less certainty about the type being handled. It could be an Apple or a Banana, making it challenging to determine without manual intervention. By default, only properties common to both types can be accessed in such scenarios.
If one wishes to interact specifically with either apples or bananas, additional code must be written to identify the type being dealt with. One method is utilizing the in
operator to check for the presence of specific properties:
const Example = (entry: Entry) => {
if ('appleTitle' in entry.entryItem) {
// Within this block, TypeScript confirms item as an Apple, enabling access to unique apple properties.
console.log(entry.entryItem.appleTitle);
} else {
console.log(entry.entryItem.bananaTitle);
}
}
Alternatively, transforming types into a "discriminated union" by introducing a distinguishing property common to both types can help differentiate between them:
export type Banana = {
type: 'banana',
number: number,
bananaTitle: string
}
export type Apple = {
type: 'apple',
number: number,
appleTitle: string
}
// implementation example:
const Example = (entry: Entry) => {
if (entry.entryItem.type === 'apple') {
// Within this block, TypeScript recognizes item as an Apple, facilitating exclusive access to apple properties.
console.log(entry.entryItem.appleTitle);
} else {
console.log(entry.entryItem.bananaTitle);
}
}
A third approach involves establishing a user-defined type guard