TypeScript: Could not find a declaration file for

2019-07-31 11:42发布

问题:

I'm using TypeScript with Visual Studio Code on Windows 10 to develop an NPM module. I use mocha/chai combined with nyc (istanbul) for unit testing and code coverage.

For some of my tests I would like to use chai-bytes to compare buffers more easily. Unfortunately, there is no type definition file in the chai-bytes module and there is no definition at @types/chai-bytes available.

Therefore, I have written my own type definition file for the chai-bytes plugin (which is very simple), but during execution of npm test I get the following error:

TSError: ⨯ Unable to compile TypeScript:
test/utls/BitArray-test.ts(3,23): error TS7016: Could not find a declaration file for module 'chai-bytes'. 'C:/Users/<user>/Source/Repos/velux-api/node_modules/chai-bytes/index.js' implicitly has an 'any' type.
  Try `npm install @types/chai-bytes` if it exists or add a new declaration (.d.ts) file containing `declare module 'chai-bytes';`
test/utls/BitArray-test.ts(48,38): error TS2339: Property 'equalBytes' does not exist on type 'Assertion'.

VS Code provides me with full Intellisense, so I think my type definition file works and is found at least by VS Code.

This is my directory structure:

dist\              <-- My compiled code goes here
  utils\
    BitArray.d.ts
    BitArray.js
    BitArray.js.map
  index.d.ts
  index.js
  index.js.map
  ...
src\
  utils\
    BitArray.ts
  index.ts
  ...
test\
  utils\
    BitArray-test.ts
  ... (other test files)
  mocha.opts
types\
  chai-bytes\
    index.d.ts       <-- Type definition file for 'chai-bytes'

I have tried to move the type definition file to the source tree (several places), but with no effect, besides, that sometimes it got even worse, so that even VS Code haven't found it anymore.

These are my config files:

package.json:

{
      "name": "klf-200-api",
      "version": "3.0.0",
      "description": "This module provides a wrapper to the socket API of a Velux KLF-200 interface. You will need at least firmware 0.2.0.0.71 on your KLF interface for this library to work.",
      "main": "dist/index.js",
      "types": "dist/index.d.ts",
      "author": {
        "name": "Michael Schroeder"
      },
      "dependencies": {
        "@types/promise-timeout": "^1.3.0",
        "promise-timeout": "^1.3.0"
      },
      "devDependencies": {
        "@types/chai": "^4.1.6",
        "@types/chai-as-promised": "^7.1.0",
        "@types/mitm": "^1.3.2",
        "@types/mocha": "^5.2.5",
        "@types/node": "^10.11.7",
        "@types/sinon": "^5.0.7",
        "@types/sleep": "0.0.7",
        "babel-eslint": "^8.0.0",
        "chai": "^4.1.0",
        "chai-as-promised": "^7.1.1",
        "chai-bytes": "^0.1.1",
        "chai-sinon": "^2.8.1",
        "cross-env": "^5.2.0",
        "eslint": "^4.7.1",
        "eslint-config-defaults": "^9.0.0",
        "eslint-plugin-react": "^7.3.0",
        "gulp": "^4.0.0",
        "gulp-release-it": "^2.0.14",
        "gulp-typescript": "^5.0.0-alpha.3",
        "gulp-uglify": "^3.0.1",
        "istanbul": "^0.4.5",
        "mitm": "^1.4.0",
        "mocha": "^3.4.2",
        "nock": "^9.0.14",
        "nyc": "^13.1.0",
        "sinon": "^7.1.1",
        "sleep": "^5.2.3",
        "source-map-support": "^0.5.9",
        "ts-mocha": "^2.0.0",
        "ts-node": "^7.0.1",
        "typescript": "^3.1.2",
        "uglify-es": "^3.3.9"
      },
      "scripts": {
        "test": "cross-env TS_NODE_FILES=true nyc mocha",
        "document": "jsdoc src -r -c ./.jsdoc.json -d docs"
      },
      "nyc": {
        "include": [
          "src/**/*.ts",
          "src/**/*.tsx"
        ],
        "extension": [
          ".ts",
          ".tsx"
        ],
        "exclude": [
          "**/*.d.ts"
        ],
        "reporter": [
          "text-summary",
          "html"
        ],
        "all": true
      },
      "repository": {
        "type": "git",
        "url": "https://github.com/MiSchroe/klf-200-api"
      },
      "keywords": [
        "klf-200",
        "IoT"
      ],
      "license": "MIT",
      "bugs": {
        "url": "https://github.com/MiSchroe/klf-200-api/issues"
      },
      "homepage": "https://mischroe.github.io/klf-200-api/"
    }

tsconfig.json:

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es6",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    "outDir": "./dist",                        /* Redirect output structure to the directory. */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */

    /* Module Resolution Options */
    "esModuleInterop": true                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  },
  "include": [
    "./src/**/*"
  ]
}

mocha.opts:

--require ts-node/register
--require source-map-support/register
--recursive
--full-trace
--bail
test/**/*.ts

types\chai-bytes\index.d.ts:

/// <reference types="chai" />

declare module "chai-bytes" {
    function chaiBytes(chai: any, utils: any): void;

    export = chaiBytes;
}

declare namespace Chai {

    // For BDD API
    interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
        equalBytes(expected: string | Array<number> | ArrayLike<number>): void;
    }

}

BitArray-test.ts (only the relevant test):

import { expect } from "chai";
import { bitArrayToArray, arrayToBitArray } from "../../src/utils/BitArray";
import chaibytes from "chai-bytes";

'use strict';

chai.use(chaibytes);

describe("...", function() {
            it("should return an the correctly filled buffer", function() {
                const nums: number[] = [0, 2, 4, 6, 8, 10, 12, 14];
                const result = arrayToBitArray(nums, 2);

                expect(result).to.be.an.instanceof(Buffer);
                expect(result).to.be.equalBytes([0x55, 0x55]);
            });
});

npm --version: 3.10.10

node --version: v6.11.1

I could use Buffer.compare as work-around instead, but then I wouldn't see the buffers' content in the error message but only a -1, 0 or 1. (And it wouldn't solve the problem.)

Currently, I'm stuck at that point and any help is much appreciated.

回答1:

Ok, I have got it to work.

This is, what I have done:

tsconfig.json:

Add

"typeRoots": [
  "./node_modules/@types",
  "./types"
]                       /* List of folders to include type definitions from. */

to the compilerOptions list.

Change the header of the BitArray-test.ts file:

import { bitArrayToArray, arrayToBitArray } from "../../src/utils/BitArray";
import chaibytes from "chai-bytes";
import { expect, use } from "chai";

'use strict';

use(chaibytes);

Now, it works.