#Exporting Types when publishing to NPM

1 messages · Page 1 of 1 (latest)

modern saffron
#

Hi,

Quick question;

When creating a TypeScript module to be exported to NPM, how would one properly also deliver the types if there's no main/index file?

My lib-directory looks like this:

lib
├── FileSystemInterface.d.ts
├── FileSystemInterface.js
├── FileSystemInterface.js.map
└── file
    ├── FileSystemFile.d.ts
    ├── FileSystemFile.js
    ├── FileSystemFile.js.map
    └── content
        ├── BufferFileContent.d.ts
        ├── BufferFileContent.js
        ├── BufferFileContent.js.map
        ├── FileContentInterface.d.ts
        ├── FileContentInterface.js
        ├── FileContentInterface.js.map
        ├── StringFileContent.d.ts
        ├── StringFileContent.js
        ├── StringFileContent.js.map
        ├── Uint8ArrayFileContent.d.ts
        ├── Uint8ArrayFileContent.js
        └── Uint8ArrayFileContent.js.map

How to configure my package.json and/or tsconfig.json to properly also publish the defined type-files?

Documentation says this about it: If your package has a main.js file, you will need to indicate the main declaration file in your package.json file as well. Set the types property to point to your bundled declaration file. For example:

In my case, I don't have a entrypoint like that. So I don't need to declare it and everything should work properly?

Thanks for help!

ebon rock
#

I think that part of the documentation is outdated, pretty sure you don't need to explicitly specify as long as there is .d.ts accompanying every .js your package consumer might import.

#

Although, how do you intend your consumer to use your package, something like this?

import ... from 'my-package/lib/FileSystemInterface.js'
import ... from 'my-package/lib/file/FileSystemFile.js'
import ... from 'my-package/lib/file/content/BufferFileContent.js'
modern saffron
#

I would like just to do from 'package'

ebon rock
#

Then you need an entry point.

modern saffron
#

and then import / export from that entrypoint?

ebon rock
#

Yes everything you want to export would have to be in that entry point, otherwise people will have to reach inside your package to get stuffs.

modern saffron
#

Do you have an example for me of a package that does this?

ebon rock
#

Eh I don't know one of top of my head, but to set it up is trivial.

#

Let's say you have some stuff in deeply nested files:

// lib/file/FileSystemFile.ts

export class FileSystemFile {
    // ...
}

All you need to do is to set up an entry point, and export whatever you want the package to have:

// index.ts

export * from './lib/file/FileSystemFile.js'
// or explicitly export specific things
export { FileSystemFile } from './lib/file/FileSystemFile.js'

In your package.json, have the main field point to your entry point, and that's it.

modern saffron
#

oh that's what I was looking for

ebon rock
#

Personally I like to have an index.ts in every folder which exports everything in that folder, as well as everything in the subfolder. It's called a barrel file.
For example lib/index.ts would export everything in lib, and re-export every subfolder of lib:

export { FileSystemInterface } from './FileSystemInterface.js'

export * from './file/index.js'

lib/file/index.js would then export everything in lib/file, and re-export every subfolder of lib/file, and so on.

modern saffron
#

import type { FileSystemInterface } from '@versastore/core'; doing now that in another project.. but I get TS2307: Cannot find module '@versastore/core' or its corresponding type declarations

#
ebon rock
#

import ... from 'package/core' no longer uses the main entry point.

#

It uses the ./core entry point.

#

If you want to set up multiple entry points/non main entry points, you need to use exports field in package.json.

#

Oh wait my bad, I see the entire @versastore/core is your package name.

modern saffron
#

I called the project @versastore/core, put this in index.ts:

export * from './FileSystemInterface.js';
export * from './file/FileSystemFile.js';
export * from './file/content/BufferFileContent.js';
export * from './file/content/FileContentInterface.js';
export * from './file/content/StringFileContent.js';
export * from './file/content/Uint8ArrayFileContent.js';

And This in my package.json:

    "type": "module",
    "types": "lib/index.d.ts",
    "main": "lib/index.js",
#

Yes, correct.

gaunt oxideBOT
#
nonspicyburrito#0

Preview:```ts
import {FileSystemInterface} from "@versastore/core"

const foo: FileSystemInterface = {}```

ebon rock
#

Seems to work fine.

modern saffron
#

Then it's my local tsconfig acting, thanks for checking

#

Ah for some reason my lib driectory doesn't seem to come with the install..

ebon rock
#

Oh you don't have lib folder included in your package.json

#

You need to include that in files field of package.json, or package managers may just them.

modern saffron
#

ahhh

#

Can I just include the whole directory or only specific files?

ebon rock
#

You can yeah, "files": ["lib"].