skip to Main Content

The following is an interface.

/**
 * @interface
 */
class ISomething {
  /**
   * @return {number}
   */
  static aMethod() {
    throw new Error('not implemented');
  }

  /**
   * @type {Object}
   */
  static property;
}

The following is an implementation, and no errors happen if I don’t add the static items.

/**
 * @implements {ISomething}
 */
class Implementation {
  // forgot to implement the static items
  // no errors in VSCode
}

What I want is to similar to how interfaces work but for static items that can be accessed with respect to the class instead of object. I want some error if I forget to implement a static method. Any workarounds and hacks are appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    As stated by @Tim Hansen Javascript doesn't have interfaces and Typescript has better type support than JSDoc. Hence I've created a workaround function that checks for proper implementation of static members at runtime.

    You can create a script that imports your JS classes and if you've forgotten to implement any static memeber, error will be thrown when you run it.

    Usage of workaround

    /**
     * @interface
     */
    class ISomething {
      /**
       * @return {number}
       */
      static aMethod() {
        throw new Error('not implemented');
      }
    
      /**
       * @type {Object}
       */
      static property;
    }
    
    
    /**
     * @implements {ISomething}
     */
    class Implementation {
      // forgot to implement the static items
      // no errors in VSCode
      // enforce fn throws error
    }
    
    enforceInterfaceStaticMembers(Implementation, ISomething);
    

    Workaround function

    function enforceInterfaceStaticMembers(className, interfaceName) {
      const classStatics = Object.getOwnPropertyNames(className);
      const interfaceStatics = Object.getOwnPropertyNames(interfaceName);
    
      interfaceStatics.forEach((prop) => {
        if (!classStatics.includes(prop)) {
          throw new Error(
            `${className.name} must implement static member: ${interfaceName.name}.${prop}`
          );
        }
    
        const interfaceType = typeof interfaceName[prop];
        const classType = typeof className[prop];
    
        if (classType !== interfaceType) {
          throw new Error(
            `${className.name}'s static member '${prop}' must have the same type as in the interface (expected ${interfaceType}, found ${classType}).`
          );
        }
      });
    }
    

  2. JavaScript does not support interfaces. See for more information: Does JavaScript have the interface type (such as Java's 'interface')?

    You can use TypeScript, which does support interfaces: https://www.typescriptlang.org/docs/handbook/interfaces.html

    If you are already using TypeScript, do not declare the interface using JSDoc and rather like this:

    interface ISomething {}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search