TypeScript constructor TypeScript constructor typescript typescript

TypeScript constructor


In Typescript, function overloading is nothing more than defining additional call signatures for a single function body. And since there is only one function body, all overload signatures must be compatible with that initial function declaration. Type- and value-checking of arguments are to be done manually.

In your case, it's a bit tricky, as interface definitions are lost upon compilation, therefore you'll have no clean approach to check if the passed argument is an implementation of the given interface. Luckily, it's an "object or string" check for your first parameter, and an "exists or not" for the second, so checking whether or not the interface is implemented is unnecessary:

export class ShoppingListItem implements IShoppingListItem {    // 2 overload signatures from which you can choose on the invocation side    constructor(item: IShoppingListItem);    constructor(name: string, amount: number);    // the function declaration itself, compatible with both of the above overloads    // (in VS, IntelliSense will not offer this version for autocompletion)    constructor(nameOrItem: string | IShoppingListItem, amount?: number) {        if (typeof nameOrItem === "object") {            // the first argument is an object, due to overload signature,            // it is safe to assume it is of type IShoppingListItem            // ...        } else if (typeof nameOrItem === "string" && typeof amount === "number") {            this.name = nameOrItem;            this.amount = amount;        }    }}

Here, both overloads are compatible with the initial signature. Parameter names do not matter, only their respective types and ordering (as well as optionality).

The TypeScript compiler is aware of typeof and instanceof checks, which results in your variable being treated as the correct type inside a conditional block as such. This is called a type guard.


You can get functionality you need with static method:

export class ShoppingListItem implements IShoppingListItem {    name: string;    amount: number;    constructor(item: IShoppingListItem) {        this.name = item.name;        this.amount = item.amount;    }    static create(name: string, amount: number) {        let item: IShoppingListItem = { name, amount };        return new ShoppingListItem(item);    }}

You can create ShoppingListItem like this:

  • ShoppingListItem.create("Cat", 3)

  • ShoppingListItem({ name: "Cat", amount: 3 })