¿Cómo obtengo todos los nombres de propiedades de una clase y los uso como una variable estática en TypeScript?
En mi proyecto usando TypeScript, tengo una clase como
class Car {
model: string;
year: number;
price: string;
constructor(model: string, year: number, price: string) {
this.model = model;
this.number = number;
this.price = price;
}
}
Tengo que leer datos de un archivo json. Y lo primero, necesito comprobar que los datos del archivo tienen la misma propiedad que la clase Car. No quiero usar el código fileData.hasOwnProperty('model'). Mi idea es similar a fileData.hasOwnProperty(Car.model). Quiero hacer que las propiedades de la clase sean propiedades recomendadas estáticas de la clase Car.
Me gustaría poder referenciar cualquier propiedad en una clase, como Car.model, Car.year o Car.price, ... de una manera que devuelva el nombre de la propiedad o información similar.
¿Tienes alguna idea para eso?
Muchas gracias
Intenté algo como lo siguiente. Pero no creo que sea una buena idea. Porque en el futuro, si agrego 5 propiedades más, también tendré que agregar 5 métodos correspondientes. Y no quiero agregar más métodos en este caso.
class Car {
model: string;
year: number;
price: string;
constructor(model: string, year: number, price: string) {
this.model = model;
this.number = number;
this.price = price;
}
static model() {
return 'model';
}
static year() {
return 'year';
}
static price() {
return 'price';
}
}
También intento lo siguiente. Pero no recomendó el nombre de la propiedad cuando quiero llamar a Car.properties.model
class Car {
model: string;
year: number;
price: string;
constructor(model: string, year: number, price: string) {
this.model = model;
this.number = number;
this.price = price;
}
static properties() {
return Object.getOwnPropertyNames(Car).map((property) => { property });
}
}
Respuesta #1
Simplemente escribe un literal de arreglo en un campo estático:
class Car {
model: string;
year: number;
price: string;
constructor(model: string, year: number, price: string) {
this.model = model;
this.number = number;
this.price = price;
}
static properties = ['model', 'number', 'price'] satisfies (keyof Car)[];
}
No es posible generar esta lista dinámicamente sin instanciar un new Car.
Respuesta #2
Sugiero agregar tipos y proporcionar un esquema:
Parque infantil
interface CarInterface{
model: string;
year: number;
price: string;
}
type Types = {
string: string,
number: number,
// add more
};
type FindKey<T extends object, U> = keyof {[K in keyof T as T[K] extends U ? K : never]: any};
type Scheme<T extends object> = {[K in keyof T]: FindKey<Types, T[K]>};
interface Car extends CarInterface{};
class Car implements Car{
static scheme = {
model:'string',
year: 'number',
price:'string'
} satisfies Scheme<Car>;
constructor(data: Car) {
for(const name in Car.scheme){
if(!(name in data) || typeof (data as any)[name] !== (Car.scheme as any)[name]){
throw new Error(`Data property "${name}" is missing or has invalid type`);
}
}
Object.assign(this, data);
}
}
const car = new Car({model: 'model', year: 2000, price: '$1000'});
const car2 = new Car({model: 2000, year: 2000, price: '$1000'} as any);
