Búsqueda de sitios web

typescript - ¿Es posible inicializar un objeto dentro de la inicialización de otro objeto sin constructores?


Lo que necesito es bastante simple, solo quiero inicializar un objeto que es hijo de otro objeto que estoy inicializando. En C# se vería algo así:

var car = new Car { 
serialNumber = 25,
engine = new Engine {
    horsePower = 500
    }
}

En este código de ejemplo estoy inicializando el tipo Engine dentro de la inicialización del tipo Car. Al tratar de hacer esto con TypeScript, sin importar lo que intente, obtengo errores de sintaxis.

Aquí está mi código TypeScript:

var car: Car = new Car({
serialNumber: 25,
    engine: new Engine({ 
        horsePower: 500
    })
});

Este bloque de código simplemente no funciona, y todas las clases utilizadas en el código aquí están obviamente importadas.

¿Podría ser realmente una característica básica que no esté soportada en TypeScript?

EDIT: No hay constructor en estas clases. Así es como se ven:

export class Car { 
    serialNumber: number;
    engine: Engine;
}

Respuesta #1

Ciertamente puedes hacer esto, solo tienes que pasar los argumentos correctos al constructor.

El código que has escrito pasa un único objeto de argumento al constructor con claves. Así que tus clases deberían verse algo así:

class Car {
    constructor(args: { serialNumber: number; engine: Engine; }) { }
}

class Engine {
    constructor(args: { horsePower: number; }) { }
}

Si, sin embargo, tus clases usan múltiples argumentos de constructor con nombre, así:

class Car {
    constructor(serialNumber: number, engine: Engine) { }
}

class Engine {
    constructor(horsePower: number) { }
}

Entonces simplemente tienes que pasar tus argumentos del constructor correctamente:

const car: Car = new Car(25, new Engine(500));

EDITAR

eso requeriría que creara un constructor, lo cual es un poco molesto

Estoy un poco confundido... tu código original usa clases, así que ya deberías tener un constructor a menos que estés añadiendo cada propiedad mediante una asignación. Por favor, publica un ejemplo completo.

Si solo estás tratando de crear una estructura de objetos literales anidados, solo necesitas una interfaz, luego crear el objeto usando la notación de objeto literal normal de JS:

interface Car {
  serialNumber: number;
  engine: Engine;
}

interface Engine {
  horsePower: number;
}

const car: Car = {
  serialNumber: 25,
  engine: { 
    horsePower: 500
  }
};

Si estás tratando de asignar un literal de objeto a un tipo de clase, entonces lo estás haciendo mal. :)

EDICIÓN 2

Entonces, tienes una clase con propiedades y sin constructor. Esto significa que no puedes instanciarla con propiedades, ni anidadas ni una a la vez. Podrías escribir una función auxiliar genérica para instanciar una clase y asignar propiedades:

function create<T>(constructor: new() => T, props: Partial<T>): T {
    let instance = new constructor();
    for (let key in props) {
        instance[key] = props[key];
    }
    return instance;
}

Y luego crea un objeto de clase anidada así:

const car = create(Car, {
    serialNumber: 123,
    engine: create(Engine, {
        horsePower: 456
    })
});

Pero si tus clases realmente solo tienen propiedades, creo que te convendría más usar interfaces y literales de objetos (como en mi ejemplo anterior).

Respuesta #2

Tu respuesta es definitivamente que puedes. Pero tu sintaxis tiene un problema.

var car = new Car(
       serialNumber: 25,
      engine: new Engine{ 
      horsePower: 500
     }
 ); 

y la clase Car debería ser así:

public class Car(int serialNumber, Engine engine) {

 .....
}

Artículos relacionados