deepReadonly

2023-07-16  本文已影响0人  sweetBoy_9126

测试 case

type cases = [
  Expect<Equal<DeepReadonly<X>, Expected>>,
]

type X = {
  a: () => 22
  b: string
  c: {
    d: boolean
    e: {
      g: {
        h: {
          i: true
          j: 'string'
        }
        k: 'hello'
      }
      l: [
        'hi',
        {
          m: ['hey']
        },
      ]
    }
  }
}

type Expected = {
  readonly a: () => 22
  readonly b: string
  readonly c: {
    readonly d: boolean
    readonly e: {
      readonly g: {
        readonly h: {
          readonly i: true
          readonly j: 'string'
        }
        readonly k: 'hello'
      }
      readonly l: readonly [
        'hi',
        {
          readonly m: readonly ['hey']
        },
      ]
    }
  }
}

js 实现

function test(obj) {
  const deep = (obj) => {
    let result = {};
    if (typeof obj !== "object") {
      result = obj;
    } else {
      for (let key in obj) {
        result[`readonly ${key}`] = deep(obj[key]);
      }
    }
    return result
  };

 return deep(obj);
}

知识点

  1. 判断当前类型是否对象或数组类型
    通过 keyof T extends never => 非对象或者数组

步骤

  1. 遍历 对象的key,给key 添加 readonly
    根据 key 对应的 value,判断value是否是对象类型
  2. 如果是对象类型继续把当前的value 对象递归调用,直到 value 为基本类型就返回当前 value

ts 实现

type DeepReadonly<T> = {
  readonly [P in keyof T]: keyof T[P] extends never ? T[P] : DeepReadonly<T[P]>
}
上一篇 下一篇

猜你喜欢

热点阅读