TypeScript类构造器中如何跳过前序可选参数为后续属性赋值
你遇到的问题是JavaScript/TypeScript的位置默认参数匹配规则导致的:默认参数按传入顺序匹配,要给靠后的imageURL传值必须先给前面的bio参数传值,你直接把图片链接放在第7个参数的位置会被识别为bio的赋值,所以第三种场景无法正常生效。
有两种常用的解决方案:
方案1:不修改现有构造函数,显式传入undefined占位
如果不想调整现有构造函数的参数结构,可以在bio的位置显式传入undefined触发默认值生效,示例调用如下:
new Lifter("3","Manfred",73,107,125,220, undefined, "https://www.w3schools.com/howto/img_avatar2.png")
该方案优势是不需要修改类的原有实现,缺点是调用时需要牢记参数顺序,可读性差,参数数量增加后很容易出错。
方案2(更推荐):将可选参数封装为配置对象
把两个可选参数整合为一个可选的配置对象参数,既能明确参数含义,又能灵活选择要覆盖的默认值,修改后的类实现如下:
export class Lifter { id: string; name: string; weightclass: number; bestSnatch: number; bestCJ: number; bestTotal: number; bio: string; imageURL: string; constructor( id: string, name: string, weightclass:number, bestSnatch:number, bestCJ:number, bestTotal:number, // 新增可选配置对象参数,默认值为空对象 options: { bio?: string, imageURL?: string } = {} ) { this.id = id; this.name = name; this.weightclass = weightclass; this.bestSnatch = bestSnatch; this.bestCJ = bestCJ; this.bestTotal = bestTotal; // 解构配置对象并设置默认值 const { bio = "Default biography text", imageURL = "https://upload.wikimedia.org/wikipedia/commons/a/a0/Arh-avatar.jpg" } = options; this.bio = bio; this.imageURL = imageURL; } }
对应的四种调用场景写法清晰无歧义:
// 两个可选属性都不传 new Lifter("1","Jesper",73,107,125,220) // 仅传入bio new Lifter("2","Alfred",83,187,205,220, { bio: "Some Biography" }) // 仅传入imageURL new Lifter("3","Manfred",73,107,125,220, { imageURL: "https://www.w3schools.com/howto/img_avatar2.png" }) // 两个可选属性都传入 new Lifter("4","Sigfred",73,107,125,220, { bio: "Some other biography", imageURL: "https://www.w3schools.com/howto/img_avatar2.png" })
该方案优势是参数含义清晰,不需要记忆参数顺序,后续新增可选参数也不需要调整现有调用逻辑,可维护性更强。
内容的提问来源于stack exchange,提问作者Jalpster
相关产品推荐
相关产品推荐

