TypeScript如何将数组转为带索引签名的Person类类型对象并调用实例方法
问题错误点梳理
- 类型定义匹配错误:你定义的
B是键为id字符串、值为Person实例的对象,但你声明变量b为B[]即B类型的数组,和类型定义、后续调用逻辑都不匹配 - 基础语法错误:原
a数组中['Name5', 12, 'City5']后面缺少逗号,会直接触发语法报错;实例化Person时${index}的模板字符串写法没有加反引号,属于语法错误 - 构造函数调用错误:Person的构造函数仅接受1个包含所有属性的对象参数,你调用时传了2个参数,传参格式完全错误
- 遍历取值错误:你用map生成的每个元素是
{[id]: Person}的包裹对象,遍历时直接拿到的是这个外层对象,不是Person实例,因此不存在tellUsAboutYourself方法
正确实现代码
先修正基础定义的问题
type A = Array<[string, number, string]>; const a: A = [ ['Name1', 15, 'City1'], ['Name2', 44, 'City2'], ['Name3', 23, 'City3'], ['Name4', 73, 'City4'], ['Name5', 12, 'City5'], // 补充缺失的逗号 ['Name6', 37, 'City6'] ]; class Person { _id: string; // must be unique age: number; name: string; city: string; // 给构造函数参数加类型避免隐式any报错 constructor(data: {_id: string, age: number, name: string, city: string} | null) { if (data == null) { console.log("No data presented") } else { this._id = data._id this.age = data.age this.name = data.name this.city = data.city } } tellUsAboutYourself() { console.log( `Person with unique id = ${this._id} says:\nHello! My name is ${this.name}. I was born in ${this.city}, ${this.age} years ago.` ); } } type B = { [id: string]: Person }
实现方案1:符合B类型定义的键值对集合
如果你需要的是id为键、Person实例为值的整体对象(完全匹配B的定义):
export const b: B = {} a.forEach(([name, age, city], index) => { const id = index.toString() b[id] = new Person({_id: id, name, age, city}) }) // 调用实例方法 for (const id in b) { b[id].tellUsAboutYourself() }
实现方案2:Person实例数组
如果你不需要键值对结构,只需要Person实例的数组:
export const personList: Person[] = a.map(([name, age, city], index) => { return new Person({_id: index.toString(), name, age, city}) }) // 调用实例方法 for (const person of personList) { person.tellUsAboutYourself() }
实现方案3:保留你原有B数组的结构
如果你坚持要生成B[]类型(每个元素是单键的B对象),调用时需要先提取对象内的Person实例:
export const b: B[] = a.map(([name,age,city], index) => ({ [index]: new Person({_id: index.toString(), name, age, city}) })) // 调用实例方法 for (const personObj of b) { const person = Object.values(personObj)[0] person.tellUsAboutYourself() }
内容的提问来源于stack exchange,提问作者Ramil Tsulini
相关产品推荐
相关产品推荐

