Skip to content

feat: Add exports field with .d.mts for TypeScript ESM consumers (nod… - #364

Open
jeffrson wants to merge 1 commit into
icebob:masterfrom
jeffrson:exports-map
Open

feat: Add exports field with .d.mts for TypeScript ESM consumers (nod…#364
jeffrson wants to merge 1 commit into
icebob:masterfrom
jeffrson:exports-map

Conversation

@jeffrson

Copy link
Copy Markdown

…e16/nodenext)

When using fastest-validator in a TypeScript project with "type": "module" and "moduleResolution": "node16" or "nodenext", the default import is currently broken:

import Validator from 'fastest-validator'

const v = new Validator() // TS2351: This expression is not constructable

TypeScript determines whether a .d.ts file is ESM or CJS based on the file extension and the nearest package.json "type" field — not on how it was imported. Since fastest-validator has no "type": "module", TypeScript treats dist/index.d.ts as CJS even when loaded by an ESM consumer. In CJS interpretation, export default class Validator makes Validator a module namespace rather than a constructor.

The fix is straightforward: files with a .d.mts extension are always treated as ESM by TypeScript, regardless of the package's "type" field. Adding an exports field with an "import" condition pointing to dist/index.d.mts tells TypeScript to use the ESM-mode types when the package is imported from an ESM context.

At runtime this changes nothing — index.js is still the CJS entry point for both import and require. The .d.mts file is identical to dist/index.d.ts; only the extension differs.

CJS consumers are unaffected: the "require" condition keeps dist/index.d.ts as before.

The Deno example in the repo (import FastestValidator from "https://esm.sh/fastest-validator") actually confirms that export default class Validator is the right declaration for ESM — the type just needs to be served with ESM semantics for TypeScript to pick it up correctly.

@jeffrson

Copy link
Copy Markdown
Author

I noticed the project recently switched to Vitest, so the Jest concern that sometimes comes up with ESM migrations no longer applies. A full "type": "module" migration would make this cleaner long-term, but keeping this PR minimal seemed the safer starting point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant