Mike McCollister
Mike McCollister

Reputation: 139

JavaScript with "// @ts-check" gives me strange problem with Object.freeze enum

I have a pure JavaScript class that I have been using // @ts-check to help me find some potential problems. Most problems I have mitigated but there is a class of problems that I would like to resolve, if possible.

Here is a portion of my code:

// @ts-check 

let PopupImageAnimationState = Object.freeze( // enum
{
    // values must match keyframes names
    HIDDEN              : "hidden",
    VISIBLE             : "visible",
    FADE_IN             : "fadeIn",
    FADE_OUT            : "fadeOut",
    RECENTER            : "recenter",
    SLIDE_OUT_TO_LEFT   : "slideOutToLeft",
    SLIDE_OUT_TO_RIGHT  : "slideOutToRight",
    SLIDE_IN_FROM_LEFT  : "slideInFromLeft",
    SLIDE_IN_FROM_RIGHT : "slideInFromRight"
});

let popupImageAnimationState = PopupImageAnimationState.HIDDEN;

////////////////////////////////////////////////////////////////////
A bunch of code here that will modify popupImageAnimationState.
////////////////////////////////////////////////////////////////////

// This "if" line give me the following @ts-check problem:
// This comparison appears to be unintentional because the types '"hidden"' and '"fadeOut"' have no overlap.
if(popupImageAnimationState !== PopupImageAnimationState.FADE_OUT)
{
    console.log("not equal");
}

switch(popupImageAnimationState)
{
    // this line and the following lines give me the following (or similar) @ts-check problems:
    // Type '"fadeIn"' is not comparable to type '"hidden"'.
    case PopupImageAnimationState.FADE_IN:
    case PopupImageAnimationState.RECENTER:
    case PopupImageAnimationState.SLIDE_IN_FROM_LEFT:
    case PopupImageAnimationState.SLIDE_IN_FROM_RIGHT:
        console.log("some of them");
        break;

    default:
        console.log("the rest");
        break;
}

On the "if" line, I get the following ts-check problem:

This comparison appears to be unintentional because the types '"hidden"' and '"fadeOut"' have no overlap. ts(2367) [Ln 21, Col 4]

On the case line, I get the following (or similar) ts-check problem2:

Type '"fadeIn"' is not comparable to type '"hidden"'. ts(2678) [Ln 28, Col 10]

If I get rid of the ".freeze" on object above, the problems go away but my enum class is no longer read-only.

Any ideas of how to prevent these problems, yet stay with pure JavaScript?

Upvotes: 1

Views: 63

Answers (1)

Mike McCollister
Mike McCollister

Reputation: 139

OK. I found the problem. I had to add /** @type {string} */ before my private property.

Here is a modified vesion of my code which now uses a JavaScript class.

// @ts-check
"use strict";

class MinimalClass
{
    // private enums

    #PopupImageAnimationState = Object.freeze(
    {
        // values must match keyframes names
        HIDDEN              : "hidden",
        VISIBLE             : "visible",
        FADE_IN             : "fadeIn",
        FADE_OUT            : "fadeOut",
        RECENTER            : "recenter",
        SLIDE_OUT_TO_LEFT   : "slideOutToLeft",
        SLIDE_OUT_TO_RIGHT  : "slideOutToRight",
        SLIDE_IN_FROM_LEFT  : "slideInFromLeft",
        SLIDE_IN_FROM_RIGHT : "slideInFromRight"
    });

    // private properties

    /** @type {string} */ #popupImageAnimationState;

    // constructor

    constructor()
    {
        this.#popupImageAnimationState = this.#PopupImageAnimationState.HIDDEN;
    }

    // private methods

    #animationEnd()
    {
        switch(this.#popupImageAnimationState)
        {
            case this.#PopupImageAnimationState.FADE_IN:
            case this.#PopupImageAnimationState.RECENTER:
            case this.#PopupImageAnimationState.SLIDE_IN_FROM_LEFT:
            case this.#PopupImageAnimationState.SLIDE_IN_FROM_RIGHT:
                console.log("this.#showComplete()");
                break;

            case this.#PopupImageAnimationState.FADE_OUT:
                console.log("this.#hideComplete()");
                break;

            case this.#PopupImageAnimationState.SLIDE_OUT_TO_LEFT:
            case this.#PopupImageAnimationState.SLIDE_OUT_TO_RIGHT:
                console.log("this.show(this.#newImage)");
                break;

            default:
                console.log("ERROR");
                break;
        }
    }    
}

Upvotes: 0

Related Questions