Instantiating an extended/merged type in Typescript
Typescript lets you extend types with the &
sign, creating new mutant hybrid types. I think these are called extended types, but I’m gonna call them mutants. How do we make an instance of these mutant types?
I’ve got a Typescript class and an interface:
export class ActivityModel {
public id: number = 0;
public activityTypeId: number = 0;
public uniqueIdentifier: string = null;
public context: { [key: string]: any; } = {};
// ...
}
export interface ShortCode {
shortCode: string;
}
…and somewhere there’s a component that wants data of an intersected type, ActivityModel & ShortCode
:
const doStuff = (act : ActivityDetailModel & ShortCode) : void {
console.log(act.id, act.shortCode, "says hello");
}
How do I instantiate an object of this type, as I might need to do in a mock, for example?
Here’s a way I found:
const mockActivityFactory = (): ActivityDetailModel & ShortCode => {
let adm = new ActivityDetailModel;
let mockActivity: ActivityDetailModel & ShortCode = {
...adm,
shortCode: "ABC"
};
// Here's the setup I need for my mock
mockActivity.context = { locale: { currency: "GBP" } };
return mockActivity;
};
To break it down:
- Make a little factory function, typed as your target mutant type
- Inside it, instantiate the concrete class
- Create a new object, typed as the mutant, whose content is the spread (
...
) of the concrete class and the members of interface specified individually - Make any deep nested changes that you need
- Return the mutant 👽
Now finally I’ve ended a blog post with “Return the mutant”… all is well. Have fun! 👾
Oh, and happy Thanksgiving!! 🦃🙏