Typescript cannot find local es6 module; error TS2307: Cannot find module

17,098

Regarding ES6

Since you are trying to inter-operate with an ES6 module you will either"

a) Change your tsconfig.json to target ES6 and emit ES6 modules like this:

{
  ...
  "target": "es6",
  "module": "es6",
  ...
}

However I don't think you can use ES6 modules yet in NodeJS.

or:

b) Let TypeScript transpile the ES6 JavaScript module down to ES5 by enabling JavaScript processing in your tsconfig.json under compilerOptions - like the below and making sure that the .js file is included/not excluded:

{
  ...
  "target": "es5",
  "module": "commonjs",
  "allowJs": true,
  ...
}

Regarding your Type Declarations

Have a read at my blog on how TypeScript discovers typings/type declarations and what it expects to see here: https://ivanz.com/2016/06/07/how-does-typescript-discover-type-declarations-definitions-javascript

It appears that this JavaScript file is your own code (not an NPM module), so:

  1. You don't need the /// <reference path="../typings/convert-time.d.ts" /> as long as the file is not excluded or included in tsconfig.json
  2. Ensure convert-time.d.ts is in the same directory as convert-time.js
  3. You don't need to declare a module, so remove the declare module "convert-time" { bit. This is because by having the .d.ts next to the .js it's an "external" module rather than "ambient' (see my blog) (you will need the declare bit if e.g. you were creating typings which are living in your own code for a NPM package)

Basically:

../test/helpers/convert-time.js:

export const minutes = sec => sec * 60
export const hours = sec => minutes(sec) * 60
export const days = sec => hours(sec) * 24
export const weeks = sec => days(sec) * 24
export const years = sec => days(sec) * 365

../test/helpers/convert-time.ts.d:

export function minutes(sec: number): number;
export function hours(sec: number): number;
export function days(sec: number): number;
export function weeks(sec: number): number;
export function years(sec: number): number;

index.ts:

import { minutes, days } from '../test/helpers/convert-time';

tsconfig.json (for ES5 transpiling)

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "allowJs": true,
    "noImplicitAny": false,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "jsx": "react"
  },
  "files": [
    "/test/helpers/convert-time.ts.d",
    "/test/helpers/convert-time.js",
    "index.ts"
  ]
}
Share:
17,098
Raine Revere
Author by

Raine Revere

Updated on July 08, 2022

Comments

  • Raine Revere
    Raine Revere almost 2 years

    I am having a hard time getting typescript to recognize the shape of a local es6 module:

    convert-time.js

    export const minutes = sec => sec * 60
    export const hours = sec => minutes(sec) * 60
    export const days = sec => hours(sec) * 24
    export const weeks = sec => days(sec) * 24
    export const years = sec => days(sec) * 365
    

    Note: I would like to figure out how to get this to work without just changing convert-time.js to a typescript file.

    Here is the file I am trying to import it into:

    index.ts

    /// <reference path="../typings/convert-time.d.ts" />
    
    import { minutes, days } from '../test/helpers/convert-time'
    

    Here is the type definition file I created:

    convert-time.d.ts:

    declare module "convert-time" {
      export function minutes(sec: number): number;
      export function hours(sec: number): number;
      export function days(sec: number): number;
      export function weeks(sec: number): number;
      export function years(sec: number): number;
    }
    

    And here is my tsconfig:

    tsconfig.json

    {
      "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": false,
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true,
        "jsx": "react"
      },
      "files": [
        "typings/index.d.ts",
        "typings/convert-time.d.ts"
      ],
      "exclude": [
        "node_modules"
      ]
    }
    

    Steps tried:

    None of the above worked! What dark magic must I learn to get this to work? Thanks!

  • Raine Revere
    Raine Revere almost 8 years
    Thank you, Ivan, for the thorough explanation! This did help me understand better how typescript searches for type definitions. I got rid of all of the ambient definitions and references. The build step completes successfully now, but unfortunately at runtime I get "Unexpected token export". Any ideas?
  • Ivan Zlatev
    Ivan Zlatev almost 8 years
    @Raine Where is the error coming from and what is the code?
  • Raine Revere
    Raine Revere almost 8 years
    The code is exactly as you specified. The error occurs in convert-time.js when the server starts, at run-time. It looks like an extra transpilation step is needed somewhere to convert these into commonjs modules?
  • Jamie Birch
    Jamie Birch almost 7 years
    Note: at the start of step B, commondjs should instead be written as commonjs.
  • Ivan Zlatev
    Ivan Zlatev almost 7 years
    @JamieBirch Good spot! Fixed the typo.
  • Raine Revere
    Raine Revere over 3 years
    I am unable to reproduce the exact error in the original question, but the "allowJs" advice seems to have worked for several others, and my recreation is indeed working.