website icon indicating copy to clipboard operation
website copied to clipboard

Typescript CreationAttributes are always being marked as optional with strictNullChecks disabled

Open Seth10001 opened this issue 3 years ago • 5 comments

Issue Creation Checklist

Bug Description

Typescript CreationAttributes are being marked as optional regardless of actually marking them as so. When creating a model typescript does not complain about some required parameters that are missing because of this.

Example

import { DataTypes, Model, Optional, Sequelize } from "sequelize"

interface Attributes {
    id: string
    name: string
    height: number
}

type CreationAttributes = Optional<Attributes, "id">

export default class Person extends Model<Attributes, CreationAttributes> implements Attributes {
    public id!: string
    public name!: string
    public height!: number

    public static initialize(sequelize: Sequelize) {
        this.init({
            id: {
                type: DataTypes.UUID,
                defaultValue: DataTypes.UUIDV4,
                field: "ID",
                primaryKey: true,
                allowNull: false,
            },
            name: {
                type: DataTypes.STRING,
                field: "Name",
                allowNull: false,
            },
            height: {
                type: DataTypes.NUMBER,
                field: "Height",
                allowNull: false,
            }
        }, {
            sequelize: sequelize,
            tableName: "Person"
        })
    }
}

What do you expect to happen?

It should throw a typescript error if Person.name and Person.height are not provided when creating a Person.

What is actually happening?

Typescript thinks name is optional even though it's being marked as required. Screen Shot 2022-04-06 at 3 09 48 PM

Typescript does not complain when required fields are omitted. Screen Shot 2022-04-06 at 3 10 09 PM

Environment

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

  • [x] No, I don't have the time, although I believe I could do it if I had the time...

Seth10001 avatar Apr 06 '22 19:04 Seth10001

Update: It appears to be calculating the required parameters correctly when strictNullChecks: true is configured in compilerOptions in tsconfig.json

Additionally, the parameters are being correctly calculated in [email protected] without strictNullChecks: true

Seth10001 avatar Apr 06 '22 19:04 Seth10001

We're migrating to a new way to define models to reduce the TypeScript boilerplate, this includes a new mechanism that determines whether the attribute is optional when creating a new instance.

It considers all nullable properties as being optional, because not specifying them will default to null

It does that by checking whether null can be assigned to the type (null extends T). I suppose that because when strictNullChecks is false every type will accept null, then every attribute will be considered optional

ephys avatar Apr 06 '22 20:04 ephys

Right, I tried it with InferCreationAttributes and ran into the same problem. Will strictNullChecks: true be required in the future?

For projects with strictNullChecks disabled it could require some significant refactoring to enable it. Which they should do anyways to be honest.

If strictNullChecks will be required, It'd be a good idea to leave a note about that in the documentation if it's not already

Seth10001 avatar Apr 07 '22 15:04 Seth10001

It's done inside Model so InferCreationAttributes wouldn't impact that

strictNullChecks is not required but these errors will only be caught by typescript if it's on. I'll add a note in the documentation about that

ephys avatar Apr 07 '22 15:04 ephys

I'm moving this issue to our new documentation website repository to keep better track of it

ephys avatar Apr 07 '22 15:04 ephys