如何将excludeYoungPersons函数返回数组元素的id标记为readonly且不修改原数组?
解决方案
要实现返回数组中每个元素的id属性标记为readonly且不修改原始数组,你可以按照以下步骤操作:
1. 定义带只读id的新类型
首先创建一个基于Person的新类型,仅将id属性设为readonly,其余属性保持原类型不变:
type Person = { id: string; name: string; age: number; }; // 方式1:交叉类型 + Omit,适合属性较少的场景 type PersonWithReadonlyId = { readonly id: Person['id']; } & Omit<Person, 'id'>; // 方式2:映射类型,更通用,适合属性较多或后续可能扩展的场景 // type PersonWithReadonlyId = { // [K in keyof Person]: K extends 'id' ? readonly Person[K] : Person[K]; // };
2. 修改函数返回类型并调整实现
将函数的返回类型改为readonly PersonWithReadonlyId[],同时保持数组处理逻辑不修改原数组:
function excludeYoungPersons(persons: readonly Person[]): readonly PersonWithReadonlyId[] { // 直接使用filter返回新数组,不会修改原数组 const filteredPersons = persons.filter(item => item.age > 30); // 类型断言:原元素结构与新类型完全兼容,仅通过类型系统限制id的可写性 return filteredPersons as readonly PersonWithReadonlyId[]; }
效果验证
调用函数后,返回数组中的元素id会被TypeScript禁止修改,但原始数组的元素不受影响:
const originalPersons: Person[] = [ { id: 'p1', name: '张三', age: 35 }, { id: 'p2', name: '李四', age: 28 } ]; const result = excludeYoungPersons(originalPersons); result[0].id = 'new-id'; // ❌ TypeScript报错:无法分配到 "id" ,因为它是只读属性 originalPersons[0].id = 'new-id'; // ✅ 原始数组元素的id仍可修改
关键说明
- 不修改原数组:
filter方法会返回一个全新的数组,不会改动传入的原始数组;同时我们没有修改数组中的元素对象,只是通过类型系统限制了返回值的可写性。 - 类型安全:新类型仅限制
id的可写性,其余属性的类型和可写性与原Person保持一致,保证类型兼容性。
内容的提问来源于stack exchange,提问作者Sahar
相关产品推荐
相关产品推荐

