实现 Readonly
不要使用内置的Readonly<T>
,自己实现一个。
该 Readonly
会接收一个 泛型参数,并返回一个完全一样的类型,只是所有属性都会被 readonly
所修饰。
也就是不可以再对该对象的属性赋值。
例如:
interface Todo {
title: string
description: string
}
const todo: MyReadonly<Todo> = {
title: "Hey",
description: "foobar"
}
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
复制代码
一、关键词说明
Readonly
Readonly
在 TS 中的源码实现:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
复制代码
这个从字面意思就可以理解是将一个类型的所有成员变为只读的状态。看下面的示例,肯定可以随意给name
赋值成别的字符串值。
被 readonly
标记的属性只能在声明时或类的构造函数中赋值。
与 ES6 中的 const
很相似,但 readonly
只能用在类(TS 里也可以是接口)中的属性上,相当于一个只有 getter
没有 setter
的属性的语法糖。
interface
它相当于类型中的 JS
对象,用于对函数、类等进行结构类型检查,所谓的结构类型检查,就是两个类型的结构一样,那么它们的类型就是兼容的,这在计算机科学的世界里也被成为 “鸭子类型”。
提示 什么鸭子类型? 当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
现在我们要这个 todo
对象 做一个类型注解,根据之前提到的 “鸭子类型” 的方式,我们可以定义一个 Interface 来为它做注解:
interface Todo {
content: string;
user: string;
time: string;
isCompleted: boolean;
}
const todo: Todo = {
// ...
}
复制代码
type生成interface
interface IPerson {
name: string
age: number
like: Array<string>
}
interface IPickedPerson extends Pick<IPerson, 'name' | 'like'> { } //生成新的接口
const p: IPickedPerson = { name: 'zs', like: ['a', 'b'] }
复制代码
二、Readonly 使用方式
interface USER {
name: string
age: number
}
const user: USER = {
name: 'small-yellow',
age: 23,
}
user.name = 'yellow-dog'
复制代码
用Readonly
转换一下:
const user: Readonly<USER> = {
name: 'small-yellow',
age: 23,
}
user.name = 'yellow-dog' // 错误,因为 name 仅是只读的
user.age = 23 // 错误,因为 age 也仅是只读的
Cannot assign to 'name' because it is a read-only property.
复制代码
三、题解
interface Todo {
title: string
description: string
}
//就是`keyof T` 拿到 `T` 所有属性名, 然后 `in` 进行遍历, 将值赋给 `K`, 最后 `T[K]` 取得相应属性的值时将其设置为readonly。
type MyReadonly<T> = { readonly [K in keyof T]: T[K] }
const todo: MyReadonly<Todo> = {
title: "Hey",
description: "foobar"
}
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END