overload - Sobrecarga del constructor de TypeScript con el constructor vacío
typescript error multiple constructor implementations are not allowed (4)
La última sobrecarga de funciones solo se utiliza 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 desea que id:number
esté 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 generar código de fantasía para la sobrecarga de funciones (los lenguajes tradicionales lo hacen mediante la manipulación de nombres, por ejemplo, C ++)
Así que no puedes pasar ningún parámetro o debes pasar parámetros.
En realidad, puede hacer que la sobrecarga final sea opcional, pero ninguno de los públicos 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
¿Por qué no está permitido tener definiciones de constructor
separadas en TypeScript ?
Para tener, por ejemplo, dos constructors
, necesito escribir mi código de esta manera.
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 que tengo que poner ?
Después de las cosas quiero no ser requerido.
¿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 qué TypeScript difiere de lenguajes comunes como C#
o Python
aquí?
Espero que funcione así.
constructor() {
}
constructor(id: number, name: string, surname: string, email: string) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
}
Así que no puedes pasar ningún parámetro o debes pasar parámetros.
Porque la implementación de su constructor es llamada por todos sus constructores de sobrecarga. (Técnicamente, en tiempo de ejecución solo hay una función de constructor que recibe llamadas con varias firmas de argumentos de sobrecarga).
Imagínalo 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 podría llamar a implementation_constructor
menos que el name
y la age
sean opcionales.
Puedes usar el patrón Builder para resolver esto. Incluso en C # o Python, se convierte rápidamente en un mejor enfoque a medida que crece el número de argumentos de 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);
}
}
}
Si utiliza métodos estáticos para implementar contructores 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)
}
}