Skip to content

Declare types to match ESM usage #13132

@JacobLey

Description

@JacobLey

Issue Description

Current typings are emitted such that something like:

import { where } from 'sequelize';
where()

appears to be entirely valid code.

While that is the case with Transpiled code (e.g. the above becomes something like:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sequelize_1 = require("sequelize");
sequelize_1.where();

in a commonjs module)

it is not valid when using native ESM ("type":"module"), which will result in the following error:

import { where } from 'sequelize';
         ^^^^^
SyntaxError: Named export 'where' not found. The requested module 'sequelize' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'sequelize';
const { where } = pkg;

What was unclear/insufficient/not covered in the documentation

Current typings encourage the usage of named exports from Sequelize https://sequelize.org/master/manual/typescript.html and similarly internally https://github.com/sequelize/sequelize/blob/main/types/test/where.ts

This documentation infers a commonjs environment, and is not compatible with ESM.

If possible: Provide some suggestion on how we can enhance the docs

There are 3 general approaches I can think of:

  1. Change all named exports in index.d.ts to export type to encourage usage of the default export. This would most likely be a breaking change for people that use commonjs typescript (probably 95%) but would result in the most "correct" typings
  2. Add footnote to documentation saying something like "If you use ESM, only use the default export", which would be enough to "support it" but I think it would be confusing to technically have two different usages
  3. Actually export named values. While this would actually be the best, there are a lot of exports and would require actual JS changes, which overall would require a lot more work.

Additional context

Originally brought up here: #12921 (comment)

I use Sequelize with ESM/Typescript and have run into this issue before.

using something like

import Sequelize, { Transaction } from 'sequelize';
const { Model }

class Foo extends Model {}...

export const async withTransaction(transaction?: Transaction): Promise<Foo> => Foo.findOne({ transaction })

has worked for me (e.g. use default export for Javascript values, named exports for types)

Issue Template Checklist

Is this issue dialect-specific?

  • No. This issue is relevant to Sequelize as a whole.
  • Yes. This issue only applies to the following dialect(s): XXX, YYY, ZZZ
  • I don't know.

Would you be willing to resolve this issue by submitting a Pull Request?

  • Yes, I have the time and I know how to start.
  • Yes, I have the time but I don't know how to start, I would need guidance.
  • No, I don't have the time, although I believe I could do it if I had the time...
  • No, I don't have the time and I wouldn't even know how to start.

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsFor issues and PRs. Things related to documentation, such as changes in the manuals / API reference.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions