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);
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.
pg
explicitly, add @types/pg
to your main's devDependencies
.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]dependenciesDoes 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
.
The types defined in postgres-base-class/index.d.ts
are expressed in terms of QueryConfig
and QueryResult
, which are not defined within the package, but are inherited from @types/pg
. Since the package includes @types/pg
as a devDependency
, the package of type definitions is not installed in the package that installs postgres-base-class
as a dependency. By default, tsc
acts as if the missing type definitions were any
.
The easy solution is to add @types/pg
to the dependencies
of postgres-base-class
. A better solution (that would properly isolate users from the details of the pg
package) would be to define distinct types for postgres-base-class
.
One remaining question is whether tsc
can be configured to emit a warning/error that a type referenced in an imported package is undefined.
The moral of the story is that it really is a benefit when packages include their types instead of relying on separate @types
packages.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.