Skip to content

readonly 只读

表示 变量、属性 是只读的,不能进行修改、删除、添加等操作

  1. 类型属性只读
ts
interface Pagination {
  pageSize: number;
  current: number;
  readonly total: number; // 只读不能操作
  readonly pageNumber: number; // 只读不能操作
}

let page = {
  pageSize: 10,
  current: 1,
  total: 100, // 只读不能操作
  pageNumber: 10, // 只读不能操作
};

page.current = 2; // √
// 不能修改
page.total = 88; // ×
  1. 变量只读
ts
let list: readonly number[] = [1, 2, 3];

list.push(1); // 错误的
list.pop(); // 错误的

问题

  1. 子对象是否是可读的
ts
interface Page {
  pageSize: number;
  current: number;
  total: number; // 只读不能操作
  result: {
    a: number;
  };
}

let page: Readonly<Page> = {
  pageSize: 10,
  current: 1,
  total: 100, // 只读不能操作
  result: {
    a: 1,
  },
};

page.result.a = 2; // 报错么???????

使用原生的 Readonly 是不能限制子对象的 只读能力的,所以需要自定义 Readonly

ts
type DeepReadonly<T> = {
  readonly [k in keyof T]: DeepReadonly<T[k]>; // 循环修改就行
};

这边还有一个小问题,这时候 T 可以是 任意值,那么简单类型的是否也可以么

ts
type DeepReadonly<T extends Record<string | symbol, any>> = {    // 限制对象的类型
  readonly [k in keyof T]: DeepReadonly<T[k]>; // 循环修改就行
};

拓展

  1. 高级类型 Readonly<T>

eslint-typescript

  1. prefer-readonly

  2. prefer-readonly-parameter-types

prefer-readonly-parameter-types

json
module.exports = {
  "rules": {
    "@typescript-eslint/prefer-readonly-parameter-types": "warn"
  }
};