TypeScript构造函数 [英] TypeScript constructor

查看:431
本文介绍了TypeScript构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用两个构造函数创建一个类,并发现 TypeScript 不允许这样做,但是它允许构造函数的重载,我尝试过并得到一个错误:

i tried to create a class with two constructors and find out that TypeScript are not allowing that, but it allow overloading of constructor, well I tried it to and get an error :

内部版本:重载签名与函数实现不兼容.

Build: Overload signature is not compatible with function implementation.

我的代码:

interface IShoppingListItem {
    name: string;
    amount: number;
}

export class ShoppingListItem implements IShoppingListItem{
    name: string;
    amount: number;

    constructor(item: IShoppingListItem);
    constructor(name: string, amount: number) {
        this.name = name;
        this.amount = amount;
    }

    copy() {
        //return new this.constructor(this);
    }
}

我有两个问题,第一个,为什么我不能重载构造函数,我想我做错了.

I have two question, first one, why can't I overloading the constructor, I guess I'm doing something wrong.

但是我的第二个问题以及更多的交互作用是,我知道我的构造函数得到了可选的值.我可以(不使用方法中的代码!)在构造函数上创建一个条件,该条件可以验证两个给定值之一必须存在,而在签名引导中是可选的,例如:

But my second question, and more interacting is, i know i constructor that get optional values. Can I, (not with the code inside the method!), create a condition on my constructor that can verify that one of the two given value have to exist, while in the signature boot are optional, like so:

constructor(item?: IShoppingListItem, name?: string, amount?: number) { 
//make a condition that item or name and amount must exist
    this.name = name;
    this.amount = amount;
}

谢谢.

推荐答案

在Typescript中,函数重载仅是定义其他单个功能主体的调用签名.而且,由于只有一个函数主体,因此所有重载签名必须与该初始函数声明兼容.参数的类型检查和值检查必须手动进行.

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).

TypeScript编译器知道typeofinstanceof检查,这将导致您的变量在条件块之内被视为正确的类型.这称为类型保护.

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.

这篇关于TypeScript构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆