3
votes

We have a private npm logging module based on pino and using typescript. We are compiling and publishing to npm. When importing the module into an application, we get the errors:

node_modules/@scope/logging/lib/index.d.ts(1,23): error TS2688: Cannot find type definition file for 'pino'
node_modules/@scope/logging/lib/index.d.ts(2,23): error TS7016: Could not find a declaration file for module 'pino'. 'C:/app/node_modules/pino/pino.js' implicitly has an 'any' type. Try `npm install @types/pino` if it exists or add a new declaration (.d.ts) file containing `declare module 'pino';`

package.json

{
  "name": "@scope/logging",
  "version": "1.0.0",
  "main": "lib/index.js",
  "typings": "lib/index.d.ts",
  "dependencies": {
    "pino": "4.16.1"
  },
  "devDependencies": {
    "@types/pino": "4.7.1",
    "typescript": "2.8.3"
  }
}

tsconfig.json:

{
  "compileOnSave": true,
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "moduleResolution": "node",
    "inlineSources": true,
    "inlineSourceMap": true,
    "declaration": true,
    "outDir": "lib",
    "baseUrl": ".",
    "typeRoots": ["node_modules/@types"],
    "paths": {
      "*": [
        "node_modules/*",
        "src/types/*"
      ]
    },
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true
  },
  "typeAcquisition": {
    "enable": true
  },
  "include": ["src/**/*"],
  "exclude": [
    "**/*.spec.ts",
    "node_modules",
    "src/**/node_modules"
  ]
}

lib/index.ts

import * as pino from 'pino';

const isProduction = process.env.NODE_ENV === 'production';
const logLevel = process.env.LOG_LEVEL ? process.env.LOG_LEVEL.toLowerCase() : (isProduction ? 'warn' : 'debug');

const logOpts: pino.LoggerOptions = {
  safe: true,
  level: logLevel,
  prettyPrint: !!isProduction,
};

export const logger = (category: string): pino.Logger => {
  return pino({
    name: category,
    ...logOpts,
  });
};

After compiling with tsc, here are the output files:

lib/index.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const pino = require("pino");
const isProduction = process.env.NODE_ENV === 'production';
const logLevel = process.env.LOG_LEVEL ? process.env.LOG_LEVEL.toLowerCase() : (isProduction ? 'warn' : 'debug');
const logOpts = {
    safe: true,
    level: logLevel,
    prettyPrint: !!isProduction,
};
exports.logger = (category) => {
    return pino(Object.assign({ name: category }, logOpts));
};

lib/index.d.ts

/// <reference types="pino" />
import * as pino from 'pino';
export declare const logger: (category: string) => pino.Logger;

Now after publishing, I require this module as a dependency and import it:

app/index.ts

import { logger } from '@scope/logging';
const log = logger('Application');

log.info('Working');

The error leads me to believe I need to include @types/pino/index.d.ts in my module when compiling, but I don't see how to do that.

1

1 Answers

1
votes

I think the answer is to include @types/pino as a dependency in the package.json of the module, so it's installed alongside the logging module when used in the application. It feels weird to include types as a dependency, but it has to be installed automatically and peerDependency doesn't do that.