TypeScript中如何更简洁地定义类的构造函数参数与实例属性?
简化TypeScript类构造函数与实例属性的重复定义
老哥你说的这种重复写法确实太啰嗦了,TypeScript早就给咱们准备了好几种实用的语法糖,能帮你大幅简化这个过程,不用再手动重复定义实例属性又挨个赋值了:
1. 构造函数参数加访问修饰符(最常用最简洁)
直接在构造函数的参数前面加上public、private或者protected修饰符,TypeScript会自动帮你完成三件事:创建对应的实例属性、把参数值赋值给属性、同时保留参数的类型定义。连你之前写的ConstructorProps接口都可以直接省掉:
class MyClass { constructor( public foo: number, public bar: string, public baz: boolean ) {} }
这段代码和你原来的实现功能完全一致,但行数直接砍了一半还多!
2. 要是还得保留接口怎么办?
如果你因为其他业务场景必须保留ConstructorProps接口,那也可以用对象解构或者Object.assign来简化赋值步骤:
方式一:解构赋值一次性搞定
interface ConstructorProps { foo: number; bar: string; baz: boolean; } class MyClass implements ConstructorProps { foo: number; bar: string; baz: boolean; constructor(props: ConstructorProps) { // 用解构的方式一次性把props里的值赋给实例属性 ({ foo: this.foo, bar: this.bar, baz: this.baz } = props); } }
方式二:用Object.assign批量赋值
interface ConstructorProps { foo: number; bar: string; baz: boolean; } class MyClass implements ConstructorProps { foo: number; bar: string; baz: boolean; constructor(props: ConstructorProps) { // 直接把props的所有属性拷贝到实例上 Object.assign(this, props); } }
不过要注意,Object.assign会把props里的所有可枚举属性都拷贝过来,如果props里有额外的属性,也会被加到实例上,所以如果需要严格控制属性的话,还是解构更稳妥。
3. 进阶:用satisfies做类型校验(TypeScript 4.9+)
如果你想确保构造函数的参数符合ConstructorProps的定义,但又不想让类显式实现这个接口,可以用satisfies运算符来做类型校验:
interface ConstructorProps { foo: number; bar: string; baz: boolean; } class MyClass { foo: number; bar: string; baz: boolean; constructor(props: ConstructorProps) { ({ foo: this.foo, bar: this.bar, baz: this.baz } = props satisfies ConstructorProps); } }
不过这种方式更多是锦上添花,日常开发里第一种加访问修饰符的写法才是最推荐的,简洁又符合TypeScript的惯用写法。
内容的提问来源于stack exchange,提问作者cubabit
相关产品推荐
相关产品推荐

