Best Practice way of converting from one type to another in Typescript

Viewed 6732

If I have 2 interfaces:

interface Person{
    name: string;
}

interface Employee extends Person{
    employeeId: string;
}

and I want to convert a Person to en Employee:

function employPerson(person: Person, id: string): Employee

What is the best approach?

I think that the standard way of doing this is:

function employPerson(person: Person, id: string): Employee{
    const employee = person as Employee

    employee.employeeId = id;

    return employee;
}

which works but this also works:

function employPerson(person: Person, id: string): Employee{
    const employee = person as Employee

    return employee;
}

which is obviously not right.

I like this approach:

function employPerson(person: Person, id: string): Employee{
    return {
        ...person,
        employeeId: id
    };
}

This ensures that we have all the correct properties and if I change the Employee interface to add a new property the above code will correctly error. The problem with this is that I am returning a different object - it's a clone.

How do I add a property to an existing object whilst still using full type safety?

Thanks

2 Answers

What you are asking for is to discard the type safety. This isn't inherently bad (just most times it is bad). Here, in a "conversion" function, it might be a reasonable thing to do. Here's one example:

function convertPersonToEmployee(person: Person, id: string): Employee {
    const result = person as any; // type-cast to any
    result.employeeId = id;
    return result as Employee;
}

TS Playground Link

However, unless you have actual data showing creation of a new object to be a performance issue, or data showing that you have existing code relying on modification of the function parameters, there are strong reasons to AVOID this type of in-place modification, as it makes maintenance (changing stuff) more difficult.

That said, the above does work.

Related