5

Using Typescript 4.2.3, I am building a package from Typescript. When I install the package, its entry in node-modules has .js and .d.ts files, as expected.

├── dist
│   ├── index.d.ts
│   ├── index.js
│   ├── index.test.d.ts
│   └── index.test.js
└── package.json

Here is the content of the package.json:

{
  "name": "postgres-base-class",
  "version": "0.1.3",
  "description": "Abstract class to handle an Postgres Client connection, provding execSql method to extending classes",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "devDependencies": {
<omitted>
  },
  "dependencies": {
    "pg": "^8.5.1"
  },
  "scripts": {
    "test": "jest",
    "prepack": "npm run clean && npm test && tsc --declaration",
    "clean": "tsc --build --clean"
  },
  "files": [
    "dist/"
  ],
  "author": "John Bito",
  "license": "UNLICENSED",
  "private": true
}

When I try to extend the class defined in the package, the protected method's parameters and return type are shown as any in VSCode, and tsc does not detect erroneous parameters. Instead, it appears to be treating the package as a JS package without types.

What can I do to make the types in the package available to tsc where the package is installed?

Here is the content of index.d.ts:

import { Client, QueryConfig, QueryResult } from "pg";
export type { QueryConfig } from "pg";
declare class ConnectURI {
    uriPromise: Promise<string>;
    uriString?: string;
    constructor(uri: Promise<string>);
    uri(): Promise<string>;
    toString(): string | undefined;
}
export default abstract class BasePostgresClass {
    connection?: Client;
    connectURI: ConnectURI;
    constructor(uri: Promise<string>);
    protected execSql(query: QueryConfig): Promise<QueryResult>;
    private connect;
    close(): Promise<void>;
}

The type of the execSql method where the package is imported seems to be (according to VSCode):

execSql(query: any): Promise<any>

That matches the content of index.js produced by tsc (excerpted):

class BasePostgresClass {
    constructor(uri) {
        this.connectURI = new ConnectURI(uri);
        console.debug("Got a promise for connection string");
    }
    async execSql(query) {
        console.debug("Executing query", query);
5
  • Can you share content of "dist/index.d.ts" ? Commented Mar 19, 2021 at 15:07
  • The full contents of index.d.ts and the relevant lines from index.js are now in the question, @theanurin. Commented Mar 19, 2021 at 16:18
  • 1
    Does pg contains its types build-in, or are you using a separate package for them in the devDependencies? If it is a separate package, probably you have to move it to dependencies. Commented Mar 23, 2021 at 17:49
  • Hi @KingGary! That was it!!! Would you like to add it as an anwser, so I may accept it?! Commented Mar 23, 2021 at 18:55
  • @John, I'm glad I could help you. I have added it as the answer. Thanks, and good luck with the project! Commented Mar 23, 2021 at 19:24

2 Answers 2

1

From what I can see, the pg dependency of the postgres-base-class dependency is getting shadowed by the pg dependency of the main project.

  • If your main project imports pg explicitly, add @types/pg to your main's devDependencies.
  • If not, ensure pg is NOT in the main project's dependencies (to avoid it shadowing the child's dependency types), and add @types/pg to your postgres-base-class [dev]dependencies

Working from yarn add ../relative

Sign up to request clarification or add additional context in comments.

3 Comments

While the gist of this is reasonably accurate, the devDependencies of postgres-base-class include @types/pg (obviously). It is made to work when the dependencies of postgres-base-class include @types/pg.
To add to my answer, it shouldn't matter much on either project (main or child) if it's on dependencies or devDependencies, as long as it ends up in the same node_modules folder as where TS finds pg : i.e. if main doesn't require it, it should be pulled by child's dependencies; if main depends on it, main should also include @types/pg to avoid it shadowing the @types dependency even if present under child.
You got it working when you added it to dependencies of postgres-base-class only because dependencies are pulled in when you depend on it from another package, and not when it's on devDependencies; that's why my example use it from relative import (since it did npm install on the child too, which pulled in dev-dependencies), but if you're just importing the external build, it needs to be in dependencies or [dev]Dependencies of main. tsc does NOT look [dev]dependencies fields of packages, it only look on the node_modules tree.
1

Does pg contains its types build-in, or are you using a separate package for them in the devDependencies? If it is a separate package, probably you have to move it to dependencies.

1 Comment

While this is what enabled me to resolve the problem, it's really not an answer. I'll give it an up-vote because it deserves credit, but I'll write an answer if you don't have time, @KingGary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.