【问题标题】:How to tell TypeScript that I know a method exists?如何告诉 TypeScript 我知道一个方法存在?
【发布时间】:2021-04-28 20:09:23
【问题描述】:

考虑这段代码:

export default class OptimizelyFeatureFlags implements FeatureFlags {
    private body: string;

    constructor(
        protected callEndpoint: CacheableEntity,
        protected baseUrl: string,
        protected envName: string,
        protected featureId: string
    ) {}

    /**
     * Calls the Optimizely endpoint to get the info
     */
    public async fetch(): Promise<void> {

        // Determine if this is a CallEndpoint (or child thereof)
        if (this.callEndpoint['hasAuthorisationToken'] != undefined) {
            if (!this.callEndpoint.hasAuthorisationToken()) {
                throw Error(
                    'This endpoint requires an auth token to work'
                );
            }
        }

        this.body = await this.callEndpoint.getResource(this.baseUrl + `/v2/features/${this.featureId}`);
    }

   ...

}

现在CacheableEntity是一个接口,它只需要getResource()来匹配合约。方法hasAuthorisationToken 没有在其中定义。

现在,如果一个类有一个hasAuthorisationToken() 方法,我知道它是一个CallEndpoint,它将实现CacheableEntity。这是一个类型测试——根据我的研究,我了解到 TypeScript 不提供运行时类型测试,因为在运行时它只是 JavaScript。

但是,这不会编译。在 Jest 测试中,我得到:

  ● Test suite failed to run

    src/service/feature-flags/OptimizelyFeatureFlags.ts:31:36 - error TS2339: Property 'hasAuthorisationToken' does not exist on type 'CacheableEntity'.

    31             if (!this.callEndpoint.hasAuthorisationToken()) {
                                          ~~~~~~~~~~~~~~~~~~~~~

我想有几种方法可以解决这个问题 - 也许我可以将对象从 CacheableEntity 转换为 CallEndpoint?我想告诉转译器我知道我在做什么。

或者我可以这样做:

if (this.callEndpoint['hasAuthorisationToken'] != undefined) {
    const hasAuth = this.callEndpoint['hasAuthorisationToken']();
    ...
}

但是,我想知道这是否有点混乱。解决这个问题的最佳方法是什么?

【问题讨论】:

    标签: javascript typescript typescript-typings


    【解决方案1】:

    是的,您的第一个选项是最好的。最易读。

    if (this.callEndpoint['hasAuthorisationToken'] != undefined) {
        const callEndpoint = this.callEndpoint as CallEndpoint;
        const hasAuth = callEndpoint.hasAuthorisationToken();
        ...
    }
    

    不确定!= undefined 位。你可以改用this.callEndpoint instanceof CallEndpoint 吗?不确定你是如何实例化这些东西的,但如果你可以使用instanceof,打字稿将接受对this.callEndpoint 上的方法的调用,而不需要强制转换。像这样:

    if (this.callEndpoint instanceof CallEndpoint) {
        const hasAuth = this.callEndpoint.hasAuthorisationToken();
        ...
    }
    

    【讨论】:

    • 哦,第二个选项很棒 - 谢谢。它不仅有效,而且我的基于 WebStorm 的编辑器在条件中理解 hasAuthorisationToken() 现在可以作为一种方法使用。不错!
    【解决方案2】:

    【讨论】:

    • 好东西,谢谢 - 我是 TS 之旅的新手。我想我还有一些阅读要做{ halo }。
    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 2019-03-27
    • 2016-02-14
    • 2010-11-20
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多