For in-depth information on the topic, refer to the TypeScript handbook's section on Publishing Declaration Files. Additionally, explore the DefinitelyTyped repository for a plethora of examples.
In a straightforward scenario like the one outlined in your query, the essential components required within the provider package are:
The type declaration files, notably an entrypoint declaration file named index.d.ts
.
The basic criteria to fulfill the Node.js module definition include having a package.json
manifest file with the necessary fields: name
and version
Hence, assuming your provider package directory is situated at ./provider
, the required files should be structured as follows:
./provider/package.json
:
{
"name": "@acme/types",
"version": "0.1.0"
}
./provider/index.d.ts
:
export type MyType = {
name: string;
};
An important note from the TS handbook page linked above emphasizes that if your main declaration file is named index.d.ts
and resides at the root of the package, you might not need to specify the types
property explicitly, although it's recommended.
It would be wise to define the field explicitly rather than relying solely on auto-resolution behavior:
./provider/package.json
:
{
"name": "@acme/types",
"version": "0.1.0",
"types": "./index.d.ts"
}
This addresses the query posed — but I'll also provide a sample consumer package along with steps for replication purposes.
You can either manually recreate each example file in your filesystem by copying + pasting them or utilize the provided script in your browser's JS console to download a zip archive containing the project structure:
(() => {
function createBase64DataUrl(mediaType, b64Str) {
return `data:${mediaType};base64,${b64Str}`;
}
function download(url, fileName) {
const a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
a.remove();
}
const zipArchiveData = "..."; // Base64 data truncated
const dataUrl = createBase64DataUrl("application/zip", zipArchiveData);
download(dataUrl, "so-75850348.zip");
})();
If the consumer package directory is placed at ./consumer
, it could begin with this rudimentary package file:
./consumer/package.json
:
{
"name": "consumer",
"version": "0.1.0"
}
To start off, install TypeScript and the provider types package as dev dependencies:
$ cd ./consumer
$ npm install --save-dev typescript ../provider
added 2 packages, and audited 4 packages in 616ms
found 0 vulnerabilities
You could have installed each package separately using distinct commands:
npm install --save-dev typescript
npm install --save-dev ../provider
Following installation, the package.json
will include these dependencies:
{
"name": "consumer",
"version": "0.1.0",
"devDependencies": {
"@acme/types": "file:../provider",
"typescript": "^5.0.2"
}
}
To utilize the types in code, let's craft a simple TypeScript file leveraging the types from the package:
./consumer/index.ts
:
import type { MyType } from "@acme/types";
const obj: MyType = { name: "foo" };
console.log(obj);
Subsequently, add an npm script to the package.json
for compiling the TypeScript file with default compiler settings, naming the script compile
:
{
"name": "consumer",
"version": "0.1.0",
"devDependencies": {
"@acme/types": "file:../provider",
"typescript": "^5.0.2"
},
"scripts": {
"compile": "tsc index.ts"
}
}
Typically, configuring the compiler behavior for your project using a TSConfig is recommended.
Finally, compile the file and run it:
$ npm run compile && node index.js
> [email protected] compile
> tsc index.ts
{ name: 'foo' }
The compilation proceeds smoothly without errors, and the file executes as intended.
Note that I'm utilizing Node LTS version v18.15.0 while drafting this response.
$ node --version
v18.15.0