Skip to content

Commit

Permalink
fix: improved FindOptionsWhere behavior with union types (#9607)
Browse files Browse the repository at this point in the history
* test: add test that where condition can accepts LessThan with Union

* fix: allow FindOptionsWhere to accept LessThan with Union

* added comment and simplified the type

---------

Co-authored-by: Umed Khudoiberdiev <pleerock.me@gmail.com>
  • Loading branch information
tsugitta and pleerock committed Feb 6, 2023
1 parent c77c43e commit 7726f5a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
29 changes: 17 additions & 12 deletions src/find-options/FindOptionsWhere.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@ import { EqualOperator } from "./EqualOperator"

/**
* A single property handler for FindOptionsWhere.
*
* The reason why we have both "PropertyToBeNarrowed" and "Property" is that Union is narrowed down when extends is used.
* It means the result of FindOptionsWhereProperty<1 | 2> doesn't include FindOperator<1 | 2> but FindOperator<1> | FindOperator<2>.
* So we keep the original Union as Original and pass it to the FindOperator too. Original remains Union as extends is not used for it.
*/
export type FindOptionsWhereProperty<Property> = Property extends Promise<
infer I
>
export type FindOptionsWhereProperty<
PropertyToBeNarrowed,
Property = PropertyToBeNarrowed,
> = PropertyToBeNarrowed extends Promise<infer I>
? FindOptionsWhereProperty<NonNullable<I>>
: Property extends Array<infer I>
: PropertyToBeNarrowed extends Array<infer I>
? FindOptionsWhereProperty<NonNullable<I>>
: Property extends Function
: PropertyToBeNarrowed extends Function
? never
: Property extends Buffer
: PropertyToBeNarrowed extends Buffer
? Property | FindOperator<Property>
: Property extends Date
: PropertyToBeNarrowed extends Date
? Property | FindOperator<Property>
: Property extends ObjectID
: PropertyToBeNarrowed extends ObjectID
? Property | FindOperator<Property>
: Property extends string
: PropertyToBeNarrowed extends string
? Property | FindOperator<Property>
: Property extends number
: PropertyToBeNarrowed extends number
? Property | FindOperator<Property>
: Property extends boolean
: PropertyToBeNarrowed extends boolean
? Property | FindOperator<Property>
: Property extends object
: PropertyToBeNarrowed extends object
?
| FindOptionsWhere<Property>
| FindOptionsWhere<Property>[]
Expand Down
12 changes: 12 additions & 0 deletions test/github-issues/9152/entity/Test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Column, Entity, PrimaryGeneratedColumn } from "../../../../src"

export type ValueUnion = 1 | 2 | 3

@Entity()
export class Test {
@PrimaryGeneratedColumn({ unsigned: true })
id: number

@Column()
value: ValueUnion
}
39 changes: 39 additions & 0 deletions test/github-issues/9152/issue-9152.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "reflect-metadata"
import { expect } from "chai"
import { Test, ValueUnion } from "./entity/Test"
import { DataSource } from "../../../src/data-source/DataSource"
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases,
} from "../../utils/test-utils"
import { LessThan } from "../../../src"

describe("github issues > #9152 Can't use LessThan for Union field", () => {
let connections: DataSource[]
before(
async () =>
(connections = await createTestingConnections({
entities: [Test],
})),
)
beforeEach(() => reloadTestingDatabases(connections))
after(() => closeTestingConnections(connections))

it("should not raise TypeScript error when LessThan with Union is passed to FindOptionsWhere", () =>
Promise.all(
connections.map(async (connection) => {
await connection.getRepository(Test).save({
value: 1,
})

const value = 2 as ValueUnion

const count = await connection.getRepository(Test).countBy({
value: LessThan(value),
})

expect(count).to.eq(1)
}),
))
})

0 comments on commit 7726f5a

Please sign in to comment.