【发布时间】:2018-02-03 20:55:36
【问题描述】:
在我的项目中,我时不时地创建带有构造函数的类,这些构造函数缓存它们创建的对象,这样如果构造函数被多次调用时使用相同的参数,它每次都返回相同的实例,而不是创建一个新的实例与已创建的相同。
这是一个最小的例子:
class X {
private static __cache: Record<string, X> = Object.create(null);
readonly name: string; // The compilation error happens on this line.
constructor(name: string) {
const cached = X.__cache[name];
if (cached !== undefined) {
return cached;
}
this.name = name;
X.__cache[name] = this;
}
}
这段代码在 TypeScript 上工作得很好,直到我移到 2.7 并打开 strictPropertyInitialization 。现在我在readonly name: string; 上收到一个错误,说
属性“名称”没有初始化器,也没有在构造函数中明确分配。
我的项目中有多个具有上述模式的类,因此我需要提出一个或多个通用解决方案来消除错误。
两种我不想要的解决方案:
关闭
strictPropertyInitialization。我发现它一般来说太有用了,不能关闭它。打开它会显示一些需要更新的定义,以更好地反映我的某些类的工作方式,或者提示初始化代码的改进。向
name添加明确的赋值断言,使其声明为readonly name!: string;。感叹号导致 TypeScript 不再检查是否明确分配了name。这消除了错误,但它也在编译器检查我的口味中打了一个太大的洞。例如,如果我使用断言并且我不小心在上面的代码中删除了赋值this.name = name,那么 TypeScript 不会引发错误。我喜欢尽早收到错误通知。
我在上面展示了一个最小的示例,但在我的应用程序中,我的类具有更多字段,或者是通过非常昂贵的计算创建的字段,而不仅仅是从构造函数参数中分配的。
【问题讨论】: