Tengo la tarea de transformar una matriz de tipo A en un objeto con objetos de clase Persona. Lo hice con éxito pero no puedo invocar métodos de la clase Persona usando una matriz transformada. Esto es lo que no puedo entender porque todas las comprobaciones de console.log muestran que todo se transforma bien y b contiene exactamente instancias de clase Person y no solo matrices con datos.
Así que mi código se presenta aquí:
import crypto from "crypto" type A = Array<[string, number, string]>; type B = { [id: string]: Person } export class Person { _id: string; // must be unique age: number; name: string; city: string; constructor(name: string, age: number, city: string) { this._id = Person.generateUniqueID(12); this.age = age this.name = name this.city = city } private static generateUniqueID(len: number): string { return crypto.randomBytes(Math.ceil(len/2)) .toString('hex') .slice(0, len); } public tellUsAboutYourself(): string { console.log( `Person with unique id = ${this._id} says:\n Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.` ); return `Person with unique id = ${this._id} says:\n Hello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.` } } export const a: A = [ ['name1', 24, 'city1'], ['name2', 33, 'city2'], ['name3', 61, 'city3'], ['name4', 60, 'city4'] ]; export const b: B = a.reduce(function (value: any, [name, age, city]) { let persona = new Person(name, age, city); value[persona._id] = [persona.name, persona.age, persona.city] return value; }, {});a se transforma con éxito en b, el registro de la consola para b se ve así:
{ 'd85750baf38f': [ 'name1', 24, 'city1' ], '1f8fc00c6762': [ 'name2', 33, 'city2' ], '8bac45ed719b': [ 'name3', 61, 'city3' ], '1f00fa9086a2': [ 'name4', 60, 'city4' ] }el registro de la consola para Object.keys(b) es:
[ 'd85750baf38f', '1f8fc00c6762', '8bac45ed719b', '1f00fa9086a2' ]Entonces, ¿cómo es que cuando hago:
Object.keys(b).forEach(key => { b[key].tellUsAboutYourself(); })en el compilador tsc dice:
exports.b[key].tellUsAboutYourself(); ^ TypeError: exports.b[key].tellUsAboutYourself is not a functionSu objeto b no tiene ninguna instancia de Person() . Simplemente está pegando propiedades que no son de método.
Como puede ver a continuación, ninguna de las propiedades en b no tiene una instancia de objeto, sino solo una matriz.
{ 'd85750baf38f': [ 'name1', 24, 'city1' ], '1f8fc00c6762': [ 'name2', 33, 'city2' ], '8bac45ed719b': [ 'name3', 61, 'city3' ], '1f00fa9086a2': [ 'name4', 60, 'city4' ] } Cuando haga lo siguiente, cada propiedad de b será una instancia de Person y tendrá el método: tellUsAboutYourself
export const b: B = a.reduce(function (value: any, [name, age, city]) { let persona = new Person(name, age, city); value[persona._id] = persona; return value; }, {}); Una mejor manera de escribir su bucle final puede ser usando Object.values() , por lo que tiene directamente los valores individuales:
Object.values(b).forEach(obj => { obj.tellUsAboutYourself(); })pero esto es solo una mejora.
Cuando tu lo hagas
value[persona._id] = [persona.name, persona.age, persona.city]
dentro de reduce, no está guardando el objeto Person, solo está poniendo sus atributos en una matriz. Esta matriz no tendrá los métodos de Person. Deberías hacer
value[persona._id] = persona
en cambio.