How can I create a function that takes two similar types and at the same time returns them?
My example:
type First = {
name: string,
address: string,
}
type Second = {
name: string,
email: string,
}
type Third = First | Second;
function addSuffix(payload: Third): Third {
payload.name += "suffix";
return payload;
}
const a: First = {
"name": "John",
"address": "London",
}
const b: Second = {
"name": "Alice",
"email": "alice@alice.com"
}
function doA(payload: First): First {
// some operations
return addSuffix(payload);
}
function doB(payload: Second): Second {
// some operations
return addSuffix(payload);
}
doA(a);
doB(b);
It’s not working because of:
Type ‘Third’ is not assignable to type ‘First’. Property ‘address’ is
missing in type ‘Second’ but required in type ‘First’.
How can I change the addSuffix function to make it work? In other OOP language programming, I would use interfaces (interface with name property), but how to do it in TypeScript?
>Solution :
The issue is that the function signature of addSuffix
doesn’t express the fact that it will always return the same type you pass in. This means that doA
and doB
can’t be sure that it will return the type they’re expecting.
In other OOP language programming I would use interfaces (interface with name property), but how to do it in TypeScript?
Luckily, TypeScript also has interfaces:
interface Nameable {
name: string;
}
function addSuffix<T extends Nameable>(payload: T): T {
payload.name += "suffix";
return payload;
}
You don’t have to manually implement Nameable
for First
and Second
, as it is implied by the fact they both have name
fields.
It’s also worth noting that you can also use a type alias instead of an interface to achieve the same thing, just with slightly different syntax:
type Nameable = {
name: string
}
function addSuffix<T extends Nameable>(payload: T): T {
payload.name += "suffix";
return payload;
}
Or you can even inline it:
function addSuffix<T extends { name: string }>(payload: T): T {
payload.name += "suffix";
return payload;
}