Pregunta Sobrecarga de Constructor de TypeScript con Constructor Vacío


Por qué no está permitido tener separadamente constructor definiciones en Mecanografiado?
Para tener, p. dos constructors, Necesito escribir mi código así.

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

Por lo tanto, necesito poner ? después de las cosas que quiero que no se requiera

¿Por qué no puedo escribirlo así?

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;
}

De modo que para cada constructor todos los parámetros son obligatorios.

Además, necesito tener un constructor vacío. Esto se vuelve aún más extraño, ya que necesito marcar cada parámetro con un ?.

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

Por que Mecanografiado difiere de los lenguajes comunes como C# o Python ¿aquí?

Esperaría que funcionara así.

constructor() {

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

Entonces puede pasar ningún parámetro o debe pasar parámetros.


21
2018-03-14 21:41


origen


Respuestas:


Debido a que todos los constructores de sobrecarga invocan su implementación de constructor. (Técnicamente, en el tiempo de ejecución solo hay una función de constructor que se llama con las diversas firmas de argumentos de sobrecarga).

Imagínate así:

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

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

Pensando en esto de esta manera, overload_constructor no pudo llamar implementation_constructor a no ser que name y age son opcionales


15
2018-03-14 21:51



La última sobrecarga de función solo se usa en la implementación y no está disponible públicamente. Esto se muestra a continuación:

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

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

Si tu quieres id:number para estar disponible públicamente, por supuesto, puede agregar otra sobrecarga:

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

La razón es que TypeScript intenta no hacer una generación de código sofisticada para la sobrecarga de funciones (los lenguajes tradicionales hacen esto usando el mangle de nombre, por ejemplo, C ++)

Entonces puede pasar ningún parámetro o debe pasar parámetros.

De hecho, puede hacer que la sobrecarga final sea opcional, pero ninguna de las públicas como opcional. Considere el siguiente ejemplo:

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

18
2018-03-14 23:39



Puedes usar el patrón de Constructor para resolver esto. Incluso en C # o Python, rápidamente se convierte en un mejor enfoque a medida que crece la cantidad de argumentos de los constructores.

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);
    }
  }
}

0
2018-05-03 13:12



Si usa métodos estáticos para implementar constructores de sobrecarga, consulte.

export class User implements IUser {
     constructor(
        private _id: string,
        private _name: string,
        private _email: string,
      ) {}
    static New(jsonUser:string){
        return new User(
            JSON.parse(jsonUser).id,
            JSON.parse(jsonUser).name,
            JSON.parse(jsonUser).email)
    }
}

-1
2018-04-23 21:11