Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typing errors when using nested creates with associations #1743

Open
hdeleon99 opened this issue Apr 1, 2025 · 0 comments
Open

Typing errors when using nested creates with associations #1743

hdeleon99 opened this issue Apr 1, 2025 · 0 comments

Comments

@hdeleon99
Copy link

hdeleon99 commented Apr 1, 2025

Issue

Following methods do not accept an object with an association,

  • Model.create()

Versions

  • "sequelize": "^6.37.6"
  • "sequelize-typescript": "^2.1.6"

My tsconfig has no strict mode settings enabled. Interestingly, this problem doesn't occur when strictNullChecks is enabled. My tsconfig:

{
  "compilerOptions": {
    "outDir": "./dist",
    "allowJs": true,
    "module": "commonjs",
    "target": "ES2020",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["./src/**/*"]
}

Explanation

I am using sequelize and typescript in a project. I am receiving an error when trying to create a new instance of a model while including one of its hasOne associations. Relevant documentation on the matter: https://sequelize.org/docs/v6/advanced-association-concepts/creating-with-associations/.

// Model A
  export class ModelA extends Model<
    InferAttributes<ModelA>,
    InferCreationAttributes<ModelA>
  > {
  // ... Other fields/columns, skipping for brevity 

  @HasOne(() => ModelB, { onDelete: "SET NULL" })
  modelB: ModelB; 
  }

// Model B
  export class ModelB extends Model<
    InferAttributes<ModelB>,
    InferCreationAttributes<ModelB>
  > {
    @BelongsTo(() => ModelA)
    modelA?: ModelA;
    }

And when I try to create an instance of ModelA, including ModelB:

await ModelA.create({...propertiesOfModelA, 
          modelB: {...propertiesOfModelB}},
          {include: [ModelB],})

I am met with this error:

Type '<fields of modelB argument>' is missing the following properties from type 'ModelB': $add, $set, and 35 more.ts(2740)

ModelA(90, 3): The expected type comes from property 'modelB' which is declared here on type 'Optional<InferCreationAttributes<ModelA, { omit: never; }>, NullishPropertiesOf<InferCreationAttributes<ModelA, { omit: never; }>>>'

I do not expect typescript to enforce that the modelB field in the values argument contain every single field, property, and method of an instance of ModelB. I can remove the stricter typing like this:

export class ModelA extends Model {}

But then Typescript has no way to enforce the types inside of the values argument passed into the create method.

I could typecast, but this feels like a bandaid:

     await ModelA.create({...propertiesOfModelA, modelB: {...propertiesOfModelB} as ModelB,
     {include: [ModelB],})

I could also define the type of ModelA's modelB field as partial, but this incorrectly communicates that all fields and columns in ModelBare optional (even if some are specified as required/not nullable).

    @HasOne(() => ModelB, {onDelete: "SET NULL"})
    modelB: Partial<ModelB>

Even if I were to define ModelB as such, the error persists:

export class ModelB extends Model<Partial<ModelB>> {}

My goal is to maintain type strictness in all relevant model methods (specifically create), so that I can still create models with associations and ensure I'm passing in the correct types.

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

No branches or pull requests

1 participant