typescript 手动实现 Readonly

最近游戏开发的时候写出了非常神秘的代码,发现可以用泛型实现 Readonly(虽然 ts 自带这个语法糖)

这个是我的类型

type TGameData = Record<string, any>;type Condition = <T extends TGameData>(this: T) => string;

然后期望用户代码是这样的。

const cond: Condition = function () {  if (this.a > 10) return "a";if (this.b > 10) return "b";if (this.x > 12) {this.x = 1;}return "c";
};

这里 this.x = 1 会报错,提示 Property 'x' does not exist on type 'T'.ts(2339)

原因

为什么可以读(认为属性存在),但是不能写呢?这个是因为 T 的限制。

any 会绕过类型检查,所以读的时候肯定没有问题,这点毫无疑问。

而写的时候,对象的属性 x 可能是 readonly 或者 [[get]],这样的对象也满足 any 的条件,所以 ts 会禁止你写入,哪怕你对 TGameData & { x 字面量 } 提升 x 的检查,也无法绕过。

用户绕过

如果用户确实是需要副作用,可以手动

const self = this as any;

这个和我的场景确实完全符合,相当于是要用户自己手动确认。