处理 TypeScript 中未初始化 class 值的最佳方法 - 对象可能是 'null'
Best way to handle uninitialised class values in TypeScript - Object is possibly 'null'
我已经为 S3 操作创建了一个包装器 class,但是当我使用 TypeScript 编译器进行编译时,出现以下错误:
lib/Store.ts:20:15 - error TS2531: Object is possibly 'null'.
20 await this.store.upload({
我是 TypeScript 的新手,但我知道 TypeScript 正在做它的工作,并防止 await this.store.upload()
可以 运行 而 this.store
是 null
的可能性。处理这种 class 值可能尚未初始化的情况的正确方法是什么?
我的包装纸 class:
import S3 from 'aws-sdk/clients/s3';
export class Store {
storeName: string;
store: S3 | null;
initialised: boolean;
constructor(storeName: string) {
this.storeName = storeName;
this.store = null;
this.initialised = false;
}
_init(): void {
this.store = new S3();
}
async _writeToStore(data: object, path: string): Promise<void> {
if (!this.initialised) this._init();
await this.store.upload({
Bucket: this.storeName,
Key: path,
Body: data
}).promise();
}
}
我一直试图避免在构造函数中创建 classes 的新实例,因为模拟起来很尴尬。
也许将新的 class 实例传递给构造函数是最好的方法?
你可以试试
{
...
“strictNullChecks”:真,
"strictPropertyInitialization": true,
...
}
"strictNullChecks" 告诉编译器注意任何评估为 null 或 undefined 的声明变量,并在编译时引发错误 (https://www.typescriptlang.org/tsconfig#strictNullChecks)
“strictPropertyInitialization”告诉编译器引发错误 'when a class 属性 when a class 属性 was declared but not set in the构造函数'。
(https://www.typescriptlang.org/tsconfig#strictPropertyInitialization)
Typescript 给你这个错误是因为你启用了 strictNullChecks
并且你的 属性 store
有 null
作为可能的类型。
您可以执行这些选项中的任何一个
选项 1 - 删除 null
类型
您可能可以在 store
上删除 null
类型,因为您在构造函数中设置 属性 的值,而您的代码中没有任何内容将其设置为 null
:
store: S3;
选项 2 - 添加 non-null 断言运算符
或者,如果在执行 this.store.upload({...})
时 this.store
永远不会为空,那么您可以像这样添加 non-null assertion operator (!):
this.store!.upload({...})
这将告诉 Typescript 停止给出错误。请注意,这不会更改代码的运行时行为,因此仅在知道值不能为 null
或 undefined
.[=33 时才使用 !
很重要=]
选项 3 - 在
之前检查 store
的 null
值
您可以在调用 this.store.upload()
之前明确检查 this.store
是否存在空值。但是这个调用必须在同一个方法中完成,像这样:
if (!this.store) {
this.store = new S3();
}
await this.store.upload({...});
这行不通:
if (!this.store) {
this._init();
}
await this.store.upload({...});
结论
就个人而言,我会选择选项 1。我假设您为 S3
编写包装器的原因是您的消费者永远不必实例化并直接使用 S3
对象,而是实例化并使用包装器 class/object.
我已经为 S3 操作创建了一个包装器 class,但是当我使用 TypeScript 编译器进行编译时,出现以下错误:
lib/Store.ts:20:15 - error TS2531: Object is possibly 'null'.
20 await this.store.upload({
我是 TypeScript 的新手,但我知道 TypeScript 正在做它的工作,并防止 await this.store.upload()
可以 运行 而 this.store
是 null
的可能性。处理这种 class 值可能尚未初始化的情况的正确方法是什么?
我的包装纸 class:
import S3 from 'aws-sdk/clients/s3';
export class Store {
storeName: string;
store: S3 | null;
initialised: boolean;
constructor(storeName: string) {
this.storeName = storeName;
this.store = null;
this.initialised = false;
}
_init(): void {
this.store = new S3();
}
async _writeToStore(data: object, path: string): Promise<void> {
if (!this.initialised) this._init();
await this.store.upload({
Bucket: this.storeName,
Key: path,
Body: data
}).promise();
}
}
我一直试图避免在构造函数中创建 classes 的新实例,因为模拟起来很尴尬。 也许将新的 class 实例传递给构造函数是最好的方法?
你可以试试
{
...
“strictNullChecks”:真,
"strictPropertyInitialization": true,
...
}
"strictNullChecks" 告诉编译器注意任何评估为 null 或 undefined 的声明变量,并在编译时引发错误 (https://www.typescriptlang.org/tsconfig#strictNullChecks) “strictPropertyInitialization”告诉编译器引发错误 'when a class 属性 when a class 属性 was declared but not set in the构造函数'。 (https://www.typescriptlang.org/tsconfig#strictPropertyInitialization)
Typescript 给你这个错误是因为你启用了 strictNullChecks
并且你的 属性 store
有 null
作为可能的类型。
您可以执行这些选项中的任何一个
选项 1 - 删除 null
类型
您可能可以在 store
上删除 null
类型,因为您在构造函数中设置 属性 的值,而您的代码中没有任何内容将其设置为 null
:
store: S3;
选项 2 - 添加 non-null 断言运算符
或者,如果在执行 this.store.upload({...})
时 this.store
永远不会为空,那么您可以像这样添加 non-null assertion operator (!):
this.store!.upload({...})
这将告诉 Typescript 停止给出错误。请注意,这不会更改代码的运行时行为,因此仅在知道值不能为 null
或 undefined
.[=33 时才使用 !
很重要=]
选项 3 - 在
之前检查store
的 null
值
您可以在调用 this.store.upload()
之前明确检查 this.store
是否存在空值。但是这个调用必须在同一个方法中完成,像这样:
if (!this.store) {
this.store = new S3();
}
await this.store.upload({...});
这行不通:
if (!this.store) {
this._init();
}
await this.store.upload({...});
结论
就个人而言,我会选择选项 1。我假设您为 S3
编写包装器的原因是您的消费者永远不必实例化并直接使用 S3
对象,而是实例化并使用包装器 class/object.