在TypeScript中的构造函数重载

16 浏览
0 Comments

在TypeScript中的构造函数重载

有人在TypeScript中完成了构造函数重载吗?在语言规范(v 0.8)的第64页上,有描述构造函数重载的语句,但没有提供任何示例代码。

我正在尝试一个非常基本的类声明;它看起来像这样,

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}
class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;
    constructor(obj: IBox) {    
        this.x = obj.x;
        this.y = obj.y;
        this.height = obj.height;
        this.width = obj.width;
    }   
    constructor() {
        this.x = 0;
        this.y = 0;
        this.width = 0;
        this.height = 0;
    }
}

当用tsc BoxSample.ts运行时,会抛出重复的构造函数定义 - 这是显然的。任何帮助都将受到赞赏。

admin 更改状态以发布 2023年5月24日
0
0 Comments

关于构造函数的重载,一个更好的替代方法是将额外的重载实现为静态工厂方法。我认为这比在构造函数中检查所有可能的参数组合更可读和更容易理解。

在以下示例中,我们可以使用来自保险提供商的数据创建一个患者对象,其存储方式不同。为了支持创建另一种患者实例的数据结构,我们只需添加另一个静态方法,在规范化提供的数据后尽可能调用默认构造函数。

class Patient {
    static fromInsurance({
        first, middle = '', last,
        birthday, gender
    }: InsuranceCustomer): Patient {
        return new this(
            `${last}, ${first} ${middle}`.trim(),
            utils.age(birthday),
            gender
        );
    }
    constructor(
        public name: string,
        public age: number,
        public gender?: string
    ) {}
}
interface InsuranceCustomer {
    first: string,
    middle?: string,
    last: string,
    birthday: string,
    gender: 'M' | 'F'
}
const utils = { /* included in the playground link below */};
{// Two ways of creating a Patient instance
    const
        jane = new Patient('Doe, Jane', 21),
        alsoJane = Patient.fromInsurance({ 
            first: 'Jane', last: 'Doe',
            birthday: 'Jan 1, 2000', gender: 'F'
        })
    console.clear()
    console.log(jane)
    console.log(alsoJane)
}

您可以在TS Playground检查输出。


在TypeScript中,方法重载并非真正存在,可以这样说,因为它需要太多由编译器生成的代码,而TS的设计是尽可能避免这种情况。方法重载的主要用例可能是为具有魔术参数的API的库编写声明。由于处理不同可能参数集的所有重要工作都由您完成,因此我认为使用重载而不是对每种场景使用临时方法没有太多优势。

0
0 Comments

TypeScript允许您声明重载,但您只能有一个实现,并且该实现必须具有与所有重载兼容的签名。在您的示例中,这可以很容易地通过使用可选参数来完成,如下所示:\n\n

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}
class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;
    constructor(obj?: IBox) {    
        this.x = obj?.x ?? 0
        this.y = obj?.y ?? 0
        this.height = obj?.height ?? 0
        this.width = obj?.width ?? 0;
    }   
}

\n\n或者使用更一般的构造函数来进行两个重载,如下所示:\n\n

interface IBox {    
    x : number;
    y : number;
    height : number;
        width : number;
}
class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;
    constructor();
    constructor(obj: IBox); 
    constructor(obj?: IBox) {    
        this.x = obj?.x ?? 0
        this.y = obj?.y ?? 0
        this.height = obj?.height ?? 0
        this.width = obj?.width ?? 0;
    }   
}

\n\n请在 Playground 中查看。

0