Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot find module error when importing a module with exported enums

I'm trying to import a custom module that exports enum types. However, when I try to use the exported enums I get this error Error: Cannot find module 'Runescape'

The code works if I either do not use the enums, so the import statement does work, or if I move the enums into my main ts file. I've tried with the compiler option "preserveConstEnums"

tsconfig.json

{
    "compilerOptions": {
      "resolveJsonModule": true,
      "moduleResolution": "node",
      "esModuleInterop": true,
      "sourceMap": true,
      "outDir": "out",
      "target": "es6"
    }
}

Runescape.ts

declare module 'Runescape' {
...
    /**
    * @description Enum of all Runescape skills
    * @enum
    * @default
    */
    export enum SkillsEnum {
        ATTACK = 'attack',
        STRENGTH = 'strength',
        DEFENSE = 'defense',
        RANGED = 'ranged',
        PRAYER = 'prayer',
        MAGIC = 'magic',
        RUNECRAFT = 'runecraft',
        CONSTRUCTION = 'construction',
        HITPOINTS = 'hitpoints',
        AGILITY = 'agility',
        HERBLORE = 'herblore',
        THIEVING = 'thieving',
        CRAFTING = 'crafting',
        FLETCHING = 'fletching',
        SLAYER = 'slayer',
        HUNTER = 'hunter',
        MINING = 'mining',
        SMITHING = 'smithing',
        FISHING = 'fishing',
        COOKING = 'cooking',
        FIREMAKING = 'firemaking',
        WOODCUTTING = 'woodcutting',
        FARMING = 'farming'
    }
...

I expect to be able to run code like this

const OSRS_SKILLS_VALUES: string[] = Object.keys(Runescape.SkillsEnum).map(
                (key: string): string => Runescape.SkillsEnum[key]
            )

and not have the module not found error thrown

like image 709
kmm3 Avatar asked Jul 28 '19 19:07

kmm3


1 Answers

This is because Runescape.ts (at least the part you specified in your question) is not a module, it's a file that declares a module (and probably should have been named Runescape.d.ts).

Is Runescape.ts your code or a 3rd party?

If it is your code and you have additional code that makes the "Runescape" module, you should put and export that enum in that module, typescript will take care of generating the deceleration file for you. If you just want to create an enum, export it directly from "Runescape.ts" (without the module declaration).

If it's not your code and you can't modify it, you can still use it by telling typescript compiler where to find the declaration of the module, you do it by adding a reference directive (adjust the path to the actual file, if needed):

/// <reference path="Runescape.ts" />

Then you can use it by importing the module:

import * as Runescape from "Runescape";

const OSRS_SKILLS_VALUES: string[] = Object.keys(Runescape.SkillsEnum).map(
    (key: string): string => Runescape.SkillsEnum[key]
)

Or just directly the enum:

import { SkillsEnum } from "Runescape";

const OSRS_SKILLS_VALUES: string[] = Object.keys(SkillsEnum).map(
    (key: string): string => SkillsEnum[key]
)

Note that in this case, just because typescript can compile this code doesn't mean it can be executed. Because the enum is just a declaration, the actual javascript code will assume there is already a module named "Runescape" that contains the real code of that enum (actually, it's javascript equivalent, there are no enums in javascript). It is your responsibility that this module is accessible in the runtime environment (node, browser, etc).

To understand better the concepts of modules and declarations files, you should read the typescript docs on modules, namespaces and modules and other related sections in the docs.

like image 144
danielv Avatar answered Oct 01 '22 22:10

danielv