Upon reviewing a valuable suggestion from user @jonsharpe in their comment, it is recommended to converge similar functionalities on one property. For example, if both weight
and mass
convey the same idea, they should be named identically (similar to how both Person
and Dog
have a name
property conveying the same concept). Typically, this can be achieved through objects implementing a common interface, such as Massive
.
Here's a way to implement this:
interface Massive {
mass: number;
}
interface Person extends Massive {
name: string;
// other unique properties for Person
}
interface Dog extends Massive {
name: string;
// other unique properties for Dog
}
function doSomethingIfHasMass(value: Massive) {
if (value.mass === 0) return;
// perform desired action
}
const player: Person | Dog;
doSomethingIfHasMass(player);
// This assignment works without compile errors,
// as `Person | Dog` can be assigned to `Massive`
Give it a try.
This approach should address your issue (however, it's suggested to create a separate interface like Named
for the name: string
property). Additionally, another function that may be beneficial is the isMassive
, which checks if an object conforms to the Massive
interface:
function isMassive(value: object): value is Massive {
return "mass" in value;
}
Now you can pass various objects to your function, and it will gracefully handle mismatches without errors, based on whether the object structure is correct:
function doSomethingIfMassiveAndHasMass(value: object) {
if (!isMassive(value)) return;
if (value.mass === 0) return;
// perform required action
}
declare const something: object;
doSomethingIfMassiveAndHasMass(something);
// No compile errors should occur,
// as only `Massive` objects with non-zero mass will trigger its actions
Experiment with it, also check out an example.