Angular中如何实现可读不可编辑属性?TypeScript方案咨询
TypeScript实现只读属性的方案(对应Java DTO场景)
你在Java里通过类封装实现只读属性的思路,在TypeScript里有几种对应的实现方式,下面逐一说明:
1. 用Class实现(最贴近Java的写法)
TypeScript的类支持readonly修饰符,或者通过私有字段+getter的方式来实现属性只读,完全对应你Java代码的逻辑:
class Dto { // 用readonly修饰,实例化后外部无法修改 readonly id: number; // 可修改的属性(用私有字段配合getter/setter更贴近Java封装) private _desc: string; constructor(desc: string) { this._desc = desc; // 模拟生成随机ID this.id = Math.floor(Math.random() * 10000); } // 提供getter供外部读取属性 get desc(): string { return this._desc; } // 只给desc提供setter set desc(newDesc: string) { this._desc = newDesc; } } // 使用示例 const dto = new Dto('初始描述'); console.log(dto.id); // 可以读取 console.log(dto.desc); // 可以读取 dto.desc = '更新后的描述'; // 允许修改 dto.id = 123; // 编译报错,外部无法修改readonly属性
这种方式和Java的封装逻辑一致,不仅在编译阶段会阻止修改id,运行时也能保证属性不可被重新赋值。
2. 用Interface实现(类型层面的约束)
Interface在TypeScript里是类型定义工具,本身不负责实现逻辑,但可以标记属性为只读,用来约束对象的类型:
// 定义接口,标记id为只读 interface DtoInterface { readonly id: number; desc: string; } // 用函数创建符合接口的对象 function createDto(desc: string): DtoInterface { return { id: Math.floor(Math.random() * 10000), desc: desc }; } // 使用示例 const dto = createDto('初始描述'); dto.desc = '新描述'; // 允许修改 dto.id = 456; // 编译报错,不符合接口的只读约束
需要注意:这种方式只是编译阶段的类型检查,如果通过类型断言等方式绕过TypeScript的检查,运行时还是能修改id的。它更适合用来约束对象的结构,而非真正的运行时封装。
3. 用Utility Type快速实现只读属性
TypeScript提供了内置的工具类型,可以快速修改类型的只读属性,比如结合Omit来精确控制:
// 先定义基础类型 type BaseDto = { id: number; desc: string; }; // 生成仅id只读的类型 type ReadonlyIdDto = Omit<BaseDto, 'id'> & { readonly id: number }; // 创建对象 const dto: ReadonlyIdDto = { id: Math.floor(Math.random() * 10000), desc: '初始描述' }; dto.desc = '更新描述'; // 允许 dto.id = 789; // 编译报错
这种方式同样是类型层面的约束,适合快速定义类型,不需要写类的场景。
内容的提问来源于stack exchange,提问作者Sheena
相关产品推荐
相关产品推荐

