Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing different properties in a typescript union type

I'm creating a function that handles objects from the database. I have two different data structures where the same property has a different name. I can't change that, so I have to handle it in JavaScript.
The objects have other differences, but that's not important to this function.
I want to use the same function for two different types of objects. Here's sample code demonstrating my problem:

interface TypeA {
    itemName: string;
}

interface TypeB {
    itemTitle: string;
}

function getItemName(item: TypeA | TypeB): string {
    let name = '';

    if (item.hasOwnProperty('itemName')) {
        name = item.itemName;
    } else {
        name = item.itemTitle;
    }

    return name;
}

Of course, this code runs. But the IDE marks both the lines name = item.itemName; and name = item.itemTitle; as errors ("Property does not exist on type"), because both types do not have both properties.

So, what's the proper typescript way to do this?

like image 294
KWeiss Avatar asked Apr 19 '17 12:04

KWeiss


Video Answer


1 Answers

You need to create a User Defined Type Guard, then you can use an if statement and get the correct typing.

function isTypeA(value: TypeA | TypeB): value is TypeA {
    return value.hasOwnProperty('itemName');
}

Then you can get the typing much cleaner:

function getItemName(item: TypeA | TypeB): string {
    return isTypeA(item) ? item.itemName : item.itemTitle;
}

Check it out here. Item is correctly cast to either TypeA or TypeB.

like image 128
Daryl Avatar answered Sep 25 '22 08:09

Daryl