You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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属性已被初始化,无需传参:

  1. 修改checkInitialisation的签名,使其断言this的类型为原类加上storeClient非空的约束:
private checkInitialisation(): asserts this is CacheService & { storeClient: ICacheStoreInterface } {
    if (!this.storeClient) {
        throw new Error('Attempting to access cache before initialisation')
    }
}
  1. 在调用时直接调用方法,无需传参:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:40:41