Implement a generic
DeepReadonly<T>
which make every parameter of an object - and its sub-objects recursively - readonly.
https://github.com/TIMPICKLE/type-challenges/blob/main/questions/00009-medium-deep-readonly/README.md
虽然是medium,但是刷题顺序还是归为了简单题。
简单描述一下,递归的将每个对象及其子对象变为readonly
同样的,先用JS+递归形式,实现一版,找到其逻辑
function mydeepReadonly(obj){
// 首先确定返回值是一个对象
result = {};
//递归地遍历这个对象
//首先要找到递归出口
for(let key in obj){
if(obj.hasOwnProperty(key)===true){
//判断是sub节点是否为一个对象
if(obj[key] instanceof Object){
//递归入口
mydeepReadonly(obj[key]);
}else{
// 递归出口
result['readonly '+key] = obj[key];
}
}
};
return result;
};
let X = {
x: {
a: 1,
b: 'hi'
},
y: 'hey'
}
console.log(mydeepReadonly(X));
看一下ts-challenge的测试用例:
过啦!
好的现在用TS来实现一遍:
思路整理:
1. 返回一个类型
2. 对于sub-object,进行递归调用
3. 递归的时候,需要判断递归的入口和出口,ts里面就用 extends来进行类型限制
type myDeepReaonly<T> = {
readonly [P in keyof T]: T[P] extends (Record<PropertyKey, unknown>)
? myDeepReaonly<T[P]>
: T[P]
};
declare type PropertyKey = string | number | symbol; 这个很有意思,使用索引签名来检索是否为sub-object。
三元表达式来判断是否需要递归。