首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >构造函数为空的TypeScript构造函数重载

构造函数为空的TypeScript构造函数重载
EN

Stack Overflow用户
提问于 2016-03-15 05:41:08
回答 4查看 64.7K关注 0票数 41

为什么不允许在TypeScript中有单独的constructor定义?

例如,为了拥有两个constructors,,我需要像这样编写代码。

constructor(id: number)
constructor(id: number, name?: string, surname?: string, email?: string) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.email = email;
}

因此,我需要将?放在第一个构造函数中不需要的参数后面。

为什么我不能这样写呢?

constructor(id: number) {
    this.id = id;
}

constructor(id: number, name: string, surname: string, email: string) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.email = email;
}

因此,对于这两个构造函数,所有参数都是必需的。

此外,如果我需要一个空的构造函数,事情就更奇怪了,因为我需要用?标记每个参数。

constructor()
constructor(id?: number, name?: string, surname?: string, email?: string) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.email = email;
}

为什么TypeScript在这里与C#Python等常见语言不同?

我希望它是这样工作的。

constructor() {

}
constructor(id: number, name: string, surname: string, email: string) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.email = email;
}

所以你可以不传递任何参数,或者必须传递所有参数。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-03-15 05:51:50

因为所有重载构造函数都会调用您的构造函数实现。(从技术上讲,在运行时,只有一个构造函数通过各种重载参数签名进行调用。)

想象一下是这样的:

overload_constructor(id:string) {
    implementation_constructor(id);
}

implementation_constructor(id:string, name?:string, age?:number) {
    // ...
}

这样想,overload_constructor不能调用implementation_constructor,除非nameage是可选的。

另请参见Basarat的答案,该实现不会由类型检查器公开使用(尽管在运行时它是JS中使用的“真正”构造函数)。如果您想只允许()(id)(id, name, surname, email)作为唯一有效的呼叫签名,您可以这样做:

constructor()
constructor(id: number)
constructor(id: number, name: string, surname: string, email: string)
constructor(id?: number, name?: string, surname?: string, email?: string) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.email = email;
}

请注意,在实现中,所有参数都是可选的,但签名在编译时不会公开,您只能使用这些调用:

new Foo()
new Foo(1)
new Foo(1, "a", "b", "c")

不是,例如:

new Foo(1, "a")
票数 28
EN

Stack Overflow用户

发布于 2016-03-15 07:39:18

最后一个函数重载仅在实现中使用,不能公开使用。如下所示:

class Foo{
    constructor()
    constructor(id?: number) {
    }
}

const foo1 = new Foo();
const foo2 = new Foo(123); // Error! : not public

如果你想让id:number向公众开放,你当然可以添加另一个重载:

class Foo{
    constructor()
    constructor(id: number)
    constructor(id?: number) {
    }
}

const foo1 = new Foo();
const foo2 = new Foo(123); // Okay
const foo3 = new Foo('hello'); // Error: Does not match any public overload

原因是TypeScript尽量不为函数重载做花哨的代码生成(传统语言使用名称损坏,例如C++)

,因此您可以不传递参数,或者必须传递参数。

实际上,您可以将最终重载设置为可选,但不能将公共重载设置为可选。考虑以下示例:

class Foo{  
    constructor(id: number, name:string)
    constructor(name:string)
    constructor(idOrName?: number|string, name?:string) {
    }
}

const foo1 = new Foo('name'); // Okay
const foo2 = new Foo(123); // Error: you must provide a name if you use the id overload
const foo3 = new Foo(123,'name'); // Okay
票数 28
EN

Stack Overflow用户

发布于 2018-05-03 21:12:19

你可以使用Builder pattern来解决这个问题。即使在C#或Python中,随着构造函数参数数量的增加,它也会很快成为一种更好的方法。

class Foo {
  constructor(public id: number, public name: string, public surname: string, public email: string) {
  }
  static Builder = class {
    id: number = NaN;
    name: string = null;
    surname: string = null;
    email: string = null;
    Builder() {
    }
    build(): Foo {
      return new Foo(this.id, this.name, this.surname, this.email);
    }
  }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35998629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档