angulartypescriptmapkit-js

Including typings for third-party library gives module not found via angular CLI?


I am attempting to include typings for Apple's MapKit JS in my Angular 9 application, because there are no high quality typings provided by the library, nor any good third-party typings in the @types scoped package. However, Angular CLI isn't happy with how I've included my typings. The exact error I receive on compile is:

Module not found: Error: Can't resolve 'mapkit' in `components/map.component.ts`.

What am I doing wrong?

Typings

~src/types/mapkit/index.d.ts

This is where the typings are declared, and how they are declared.

declare module 'mapkit' {
  // interfaces, classes, etc here
}

Typescript Configuration

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2019",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ],
  "exclude": [
    "src/test.ts",
    "src/**/*.spec.ts"
  ]
}

Usage in code

Here is how mapkit is used.

import * as mapkit from 'mapkit';

Solution

  • Long story short: You need to rename your folder with types and add them to the type roots.

    Step #1

    In your folder with types (./types) create new folder "apple-mapkit-js"

    Step #2

    Add your custom index.d.ts there

    Step #3 Point TSC to your custom types. Update tsconfig.app.json with new typeRoots:

    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "outDir": "./out-tsc/app",
        "typeRoots" : ["./src/types/", "node_modules/@types"]
      },
      "files": [
        "src/main.ts",
        "src/polyfills.ts"
      ],
      "include": [
        "src/**/*.d.ts"
      ],
    }
    

    Step #4 Update your import to the

    import * as mapkit from 'apple-mapkit-js'
    

    Now it works.

    But what was the issue?

    Actually, according to the TypeScript documentation, if you specify typeroots, all other resources become "invisible" for the typescript, so tsc just didn't see your declarations

    P.S. Checked on the Angular 9 app.