TypeScript中如何无需传参断言类变量已初始化?
问题描述
我希望实现一个方法,告知TypeScript类中的storeClient已完成初始化(不再为null)。目前的实现需要将this.storeClient传入checkInitialisation方法进行断言,写法略显冗余。我想省去传参步骤,实现类似asserts this.storeClient is ICacheStoreInterface的效果,但该写法无法直接生效,询问是否存在可行方案。
当前实现代码:
export abstract class CacheService { storeClient: ICacheStoreInterface | null = null protected constructor(storeClientGetter: () => Promise<ICacheStoreInterface>) { this.logger = Container.get(Logger) void this.initialise(storeClientGetter) } private checkInitialisation(client: ICacheStoreInterface | null): asserts client is ICacheStoreInterface { if (!this.storeClient) { throw new Error('Attempting to access cache before initialisation') } } private async initialise(storeClientGetter: () => Promise<ICacheStoreInterface>) { try { this.storeClient = await storeClientGetter() } catch (error) { this.logger.error(`Error initialising cache service: ${error}`) } } public async set(key: storeKey, value: any) { this.checkInitialisation(this.storeClient) await this.storeClient.set(key, value) } public async get(key: storeKey) { this.checkInitialisation(this.storeClient) return this.storeClient.get(key) } } export interface ICacheStoreInterface { get(key: storeKey): Promise<any> set(key: storeKey, value: any): Promise<void> } export type storeKey = number | string | symbol
解决方案
TypeScript支持断言函数直接断言this的类型,你可以修改checkInitialisation方法,让它断言当前实例的storeClient属性已被初始化,无需传参:
- 修改
checkInitialisation的签名,使其断言this的类型为原类加上storeClient非空的约束:
private checkInitialisation(): asserts this is CacheService & { storeClient: ICacheStoreInterface } { if (!this.storeClient) { throw new Error('Attempting to access cache before initialisation') } }
- 在调用时直接调用方法,无需传参:
public async set(key: storeKey, value: any) { this.checkInitialisation() await this.storeClient.set(key, value) // TypeScript现在知道storeClient非null } public async get(key: storeKey) { this.checkInitialisation() return this.storeClient.get(key) }
修改后的完整代码:
export abstract class CacheService { storeClient: ICacheStoreInterface | null = null protected constructor(storeClientGetter: () => Promise<ICacheStoreInterface>) { this.logger = Container.get(Logger) void this.initialise(storeClientGetter) } private checkInitialisation(): asserts this is CacheService & { storeClient: ICacheStoreInterface } { if (!this.storeClient) { throw new Error('Attempting to access cache before initialisation') } } private async initialise(storeClientGetter: () => Promise<ICacheStoreInterface>) { try { this.storeClient = await storeClientGetter() } catch (error) { this.logger.error(`Error initialising cache service: ${error}`) } } public async set(key: storeKey, value: any) { this.checkInitialisation() await this.storeClient.set(key, value) } public async get(key: storeKey) { this.checkInitialisation() return this.storeClient.get(key) } } export interface ICacheStoreInterface { get(key: storeKey): Promise<any> set(key: storeKey, value: any): Promise<void> } export type storeKey = number | string | symbol
这种写法利用了TypeScript的this类型断言,调用checkInitialisation()后,TypeScript会自动推断出this.storeClient不再是null,完全省去了传参的冗余步骤。
内容的提问来源于stack exchange,提问作者Supperhero
相关产品推荐
相关产品推荐

