From b8a036d8f184153a24251ab6a0c11c0b0b35e29c Mon Sep 17 00:00:00 2001 From: Ryan Felix Date: Sat, 22 Jun 2024 19:19:01 -0400 Subject: [PATCH] SCCEE for TS type inference issue This SCCEE is expected to produce an incorrect type error when querying with `null` in the `where` clause for a nullable field. The code itself works fine, the query returns the expected results. --- src/sscce-sequelize-7.ts | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/sscce-sequelize-7.ts b/src/sscce-sequelize-7.ts index 603cb219c..67c44dc37 100644 --- a/src/sscce-sequelize-7.ts +++ b/src/sscce-sequelize-7.ts @@ -28,6 +28,10 @@ export async function run() { @Attribute(DataTypes.TEXT) @NotNull declare name: string; + + // Nullable array attribute + @Attribute(DataTypes.ARRAY(DataTypes.STRING)) + declare colors?: Array; } sequelize.addModels([Foo]); @@ -38,6 +42,33 @@ export async function run() { await sequelize.sync({ force: true }); expect(spy).to.have.been.called; - console.log(await Foo.create({ name: 'TS foo' })); + console.log(await Foo.create({ name: 'TS foo', colors: ['red', 'blue'] })); + await Foo.create({ name: 'Colorless Foo' }); expect(await Foo.count()).to.equal(1); + + // This works fine and has the expected result, but type-checking fails with + + /* + No overload matches this call. + Overload 1 of 2, '(this: ModelStatic, options: Omit>, "raw"> & { raw: true; }): Promise<...>', gave the following error. + Type '{ colors: null; }' is not assignable to type 'WhereOptions>'. + Types of property 'colors' are incompatible. + Type 'null' is not assignable to type 'WhereAttributeHashValue'. + Overload 2 of 2, '(this: ModelStatic, options?: FindOptions> | undefined): Promise<...>', gave the following error. + Type '{ colors: null; }' is not assignable to type 'WhereOptions>'. + Types of property 'colors' are incompatible. + Type 'null' is not assignable to type 'WhereAttributeHashValue'.ts(2769) + model.d.ts(104, 3): The expected type comes from property 'where' which is declared here on type 'Omit>, "raw"> & { raw: true; }' + */ + + // I _think_ the correct type for where.colors would be WhereAttributeHashValue because it is a nullable attribute of the model. + const foosWithoutColors = await Foo.findAll({ + where: { + colors: null + } + }) + + // My type-fu is not good enough to write a unit test asserting that the query type-checks... + // This is expected to pass. The code works fine, it's only a type inference problem. + expect(foosWithoutColors.length === 1) }