Associations in Typescript Sequelize

There are two simple models in a 1:N relationship - one student has many tasks.

// StudentModel.ts
interface StudentI extends Model<InferAttributes<StudentI>, InferCreationAttributes<StudentI>> {
    id: CreationOptional<number>
    name: string
    age: number
}

const StudentModel = sequelizeConn.define<StudentI>("student", {
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
    },
    name: {
        type: DataTypes.STRING(64),
        allowNull: false
    },
    age: {
        type: DataTypes.INTEGER,
        allowNull: false
    }
})

export default StudentModel
// TaksModel.ts
interface TaskI extends Model<InferAttributes<TaskI>, InferCreationAttributes<TaskI>> {
    id: CreationOptional<number>,
    student_id: number,
    definition: string
}

const TaksModel = sequelizeConn.define<TaskI>("task", {
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
    },
    student_id: {
        type: DataTypes.INTEGER,
        allowNull: false
    },
    definition: {
        type: DataTypes.STRING(64),
        allowNull: false
    }
})

export default TaksModel
// associations.ts

StudentModel.hasMany(TaksModel, { foreignKey: "student_id", as: "tasks" })
TaksModel.belongsTo(StudentModel, { foreignKey: "student_id", as: "student" })

The types of the models work fine on their own, but when dealing with relationships, the use of the "any" keyword becomes necessary.

randomFile.ts

const task = await TaksModel.findOne({
    where: {
        id: 1
    },
    include: [
        {
            model: StudentModel,
            as: "student"
        }
    ]
})
// if (task.student.age == 15 ) { } -> return Property 'student' does not exist on type 'TaskI'
if ((task as any).student.age == 15 ) { //do some stuff }

Does anyone have a better example of how to avoid using the "any" keyword? The official documentation mainly covers the types of models themselves rather than their associations.

Answer №1

To properly set up the model's interface, make sure to include a prop called student like this:

interface TaskI extends Model<InferAttributes<TaskI>, InferCreationAttributes<TaskI>> {
    id: CreationOptional<number>,
    student_id: number,
    definition: string,
    student: NonAttribute<StudentModel>
}

It appears that you mistakenly pasted the wrong model name in the code snippet below:

// You should use define for "task" instead of define<StudentI>("student"
const TaksModel = sequelizeConn.define<StudentI>("student", {

For guidance on declaring association props, refer to the official documentation here. Pay attention to how NonAttribute is utilized.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The versatile aspect of my discord bot is its ability to function with various

It's pretty strange, but my bot seems to respond to different prefixes than what I originally set. Even though I specified "-"" as the prefix in my code, the bot's commands also work with other symbols like "_", ">", "?", etc. I suspect this m ...

Angular 7 is throwing an error message that reads: "Module not found: 'AppModule'"

When running ng build, an error occurs without providing any specific details like the file name. This project is an ASP.NET Core app with Angular 7. c:\Users\siva\Myapp\ClientApp>ng build Date: 2019-08-08T13:22:52.205Z Hash: 3cf960 ...

Having trouble receiving a JSON array after making an Ajax request

I have read through previous posts on this issue, but I still can't seem to figure it out. Hopefully, someone here can help me solve this problem. My challenge lies in retrieving an array, which I have encoded in json, from a PHP script and passing i ...

Executing a TypeORM query with a distinct clause that ignores case sensitivity

I am attempting to construct a TypeORM query builder that pulls data from a postgresql database to retrieve all unique names. Here is how my query currently looks: names = await this._context.manager .getRepository(Names) .createQueryBuilde ...

In Angular 5, you can easily prevent interaction with a related button by disabling it when the corresponding reactive

I recently encountered a situation where I needed to implement a reactive form in a component. It looked something like this... form component.html <form [formGroup]="form" class="do-form"> <div formGroupName="dot"> <div class ...

Enhancing Luxon DateTime with extension type support

Referencing the issue at https://github.com/moment/luxon/issues/260, I am looking to extend the DateTime object as shown below: import { DateTime } from 'luxon'; function fromUnix(tsp?: number): DateTime { return DateTime.fromMillis(tsp * 1000 ...

Caution in NEXTJS: Make sure the server HTML includes a corresponding <div> within a <div> tag

Struggling with a warning while rendering pages in my Next.js and MUI project. Here's the code, any insights on how to resolve this would be greatly appreciated! import "../styles/globals.scss"; import { AppProps } from "next/app"; ...

What is the best way to avoid multiple triggers of an event listener in a Vue Js Component?

When I use an event listener to call a specific function, it behaves strangely. Here is the code snippet: mounted() { window.addEventListener("message", this.call); }, methods: { call(e){ if (e.data === "test"){ ...

A guide on parsing through a sequence of addresses stored in a text file and extracting specific fields using Node.js

Recently, I came across a text file containing various addresses in a specific format: 335 Ahan St. Haines City, US 30721 786 Birchmount Dr. Waterloo, IA 52001 My objective is to extract individual fields such as the street number, street name, city ...

Utilizing Node.JS and Typescript to correctly define database configuration using module.exports

I am currently utilizing Mongoose in my node.js application, which is written in Typescript. The Mongoose documentation provides clear instructions on how to connect to their database like this, but I prefer to have the configuration stored in a separate ...

The server has sent cookies headers, however, the browser did not store the cookies

I need assistance in understanding why browsers such as Chrome are not setting cookies, even though the Set-Cookie header is present in the Response Headers: Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 345 Content-Type: applicati ...

Methods for defining a variable in React with Typescript without encountering the "Index signature is missing in type" issue

I am facing an issue while trying to declare a variable 'reports' and assigning it to an array of arrays containing string and number types. The problem arises when I try to assign it, resulting in errors. ... // Retrieving data from an API let ...

The error message "Access-Control-Allow-Origin" header is not present when making an Ajax call to ReactJS localhost

While following the ReactJS tutorial, I set up a local server using the following commands: >npm install -g http-server >http-server -c-1 After successfully starting the local server at http://localhost:8080, I encountered an issue when trying to ...

Sanitize input data prior to using express-validator in a Node.js application

In my Node.js project, I am utilizing the V4 syntax of express-validator as recommended: const { check, validationResult } = require('express-validator/check'); const { matchedData } = require('express-validator/filter'); Additionally ...

`How can I stop typescript from converting dynamic imports to require()?`

Currently, I am in the process of creating a Discord bot using discord.js. Interestingly, discord.js does not seem to be compatible with ESM modules, which has been causing some complications in my project. As a result, I have resorted to utilizing CommonJ ...

What is the process for defining the root of a project in ESLint?

I've been working on a project using Next.js and Typescript. My imports look like this: import Component from "/components/Component/Component";, with the root directory being specified as /src. This setup works fine in Next.js, but ESLint k ...

A common inquiry: how can one pinpoint a location within an irregular figure?

I have been studying Html5 Canvas for a few weeks now, and the challenge mentioned above has puzzled me for quite some time. An irregular shape could be a circle, rectangle, ellipse, polygon, or a path constructed by various lines and bezier curves... I ...

Can Chrome Support Bookmarklets?

While attempting to craft a bookmarklet in Chrome using the console, I encountered the following error: Refused to load the script 'https://code.jquery.com/jquery-1.6.1.min.js' because it violates the following Content Security Policy directive: ...

Transfer the chosen nodes onto a fresh tree

Currently, I am attempting to transfer all selected nodes from one fancytree control to another on the same page. Despite my efforts with the code below, the second tree remains empty: var sourceTree= $("#tree").fancytree("getTree"); var d ...

How can I retrieve the specific error message from Express instead of seeing a generic status 500 error when a POST request fails in React?

In my React component, I am using a fetch with the post method to trigger a database update from an ExpressJS server. When the database update fails, I see the correct error message in the Express console, but in React, I only receive a 500 status error me ...