sequelize icon indicating copy to clipboard operation
sequelize copied to clipboard

Using CreationOptional leads to issues due to CreationAttributeBrand not being exported

Open eachirei opened this issue 1 year ago • 2 comments

Issue Creation Checklist

  • [X] I understand that my issue will be automatically closed if I don't fill in the requested information
  • [X] I have read the contribution guidelines

Bug Description

Typescript compilation error when using CreationOptional. error TS4053: Return type of public method from exported class has or is using name 'CreationAttributeBrand' from external module "..." but cannot be named.

Reproducible Example

import { CreationOptional, InferAttributes, InferCreationAttributes, Model } from 'sequelize';

export class Test extends Model<InferAttributes<Test>, InferCreationAttributes<Test>> {
  declare id: CreationOptional<number>;
}

in another file

class TestClass {
  async test() {
    return (await Test.create({})).id;
  }

What do you expect to happen?

Expect code to compile.

What is actually happening?

Code does not compile.

Environment

  • Sequelize version: 6.32.1
  • Node.js version: v16.17.1
  • TypeScript version: 4.9.4

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

  • [ ] Yes, I have the time and I know how to start.
  • [X] Yes, I have the time but I will need guidance.
  • [ ] No, I don't have the time, but my company or I are supporting Sequelize through donations on OpenCollective.
  • [ ] No, I don't have the time, and I understand that I will need to wait until someone from the community or maintainers is interested in resolving my issue.

Indicate your interest in the resolution of this issue by adding the 👍 reaction. Comments such as "+1" will be removed.

eachirei avatar Jul 14 '23 10:07 eachirei

We have various tests in https://github.com/sequelize/sequelize/tree/v6/test/types that use CreationOptional. Can you make a PR adding a failing test?

WikiRik avatar Jul 19 '23 09:07 WikiRik

From what I gather (i.e., my current use case), this occurs in monorepos where a package exports a branded object or function that returns a branded object that's imported by another package (without type assertions that simplify the type to remove the branding). When the package uses "declarations": true in the TSConfig (common for monorepos for IntelliSense), TypeScript tries to find CreationAttributelBrand (or any of the non-exported brands). However, since Sequelize does not export the brand types, TypeScript can't declare the types properly in the respective built .d.ts file.

The only solution is to export all branded types. While I recognize that's not meant for userland usage, it's strictly required for compilation to work in monorepos or packages.

image

image

quinnturner avatar Jan 08 '24 20:01 quinnturner