From 38428e5952c40598fbfeee840016e7e2cdbb52cc Mon Sep 17 00:00:00 2001 From: Switt Kongdachalert Date: Thu, 5 Feb 2026 22:04:52 +0700 Subject: [PATCH 1/4] added equalTo for optional arrays --- types/ParseQuery.d.ts | 4 ++-- types/tests.ts | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/types/ParseQuery.d.ts b/types/ParseQuery.d.ts index fa8e558e8..2706d8839 100644 --- a/types/ParseQuery.d.ts +++ b/types/ParseQuery.d.ts @@ -427,7 +427,7 @@ declare class ParseQuery { * @param value The value that the Parse.Object must contain. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - equalTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; + equalTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be not equal to the provided value. @@ -436,7 +436,7 @@ declare class ParseQuery { * @param value The value that must not be equalled. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - notEqualTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; + notEqualTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be less than the provided value. diff --git a/types/tests.ts b/types/tests.ts index 7a97b9f67..dd093b5b3 100644 --- a/types/tests.ts +++ b/types/tests.ts @@ -1853,6 +1853,8 @@ function testQuery() { attribute2: number; attribute3: AnotherSubClass; attribute4: string[]; + attribute5?: AnotherSubClass[]; + attribute6?: string[]; }> {} const query = new Parse.Query(MySubClass); @@ -1962,6 +1964,19 @@ function testQuery() { // $ExpectType ParseQuery query.equalTo('attribute4', ['a_string_value']); + + // Optional object[] (e.g. prop?: ClassName[] ): allow matching a single element (array contains object), and allow matching the full array + // $ExpectType ParseQuery + query.equalTo('attribute5', new AnotherSubClass()); + // $ExpectType ParseQuery + query.equalTo('attribute5', [new AnotherSubClass()]); + + // Optional string[] (e.g. prop?: string[] ): allow matching a single element (array contains string), and allow matching the full array + // $ExpectType ParseQuery + query.equalTo('attribute6', 'a_string_value'); + // $ExpectType ParseQuery + query.equalTo('attribute6', ['a_string_value']); + // $ExpectType ParseQuery query.notEqualTo('attribute4', 'a_string_value'); // $ExpectType ParseQuery @@ -1976,6 +1991,12 @@ function testQuery() { // $ExpectError query.notEqualTo('attribute4', [5]); + // Optional string[]: reject invalid element types + // $ExpectError + query.equalTo('attribute6', 5); + // $ExpectError + query.notEqualTo('attribute6', 5); + // $ExpectType ParseQuery query.exists('attribute1'); // $ExpectError @@ -2363,4 +2384,3 @@ function testInitialize() { // Node - 1 param (should also work since javaScriptKey is optional in node) ParseNode.initialize('appId'); } - From ab0b7f4e51fb04d6a6dacfe55db95cb19ba04e3b Mon Sep 17 00:00:00 2001 From: Switt Kongdachalert Date: Thu, 5 Feb 2026 22:22:01 +0700 Subject: [PATCH 2/4] fix: Allow equalTo to match for optional arrays, regenerated types --- types/ParseQuery.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/ParseQuery.d.ts b/types/ParseQuery.d.ts index 2706d8839..fa8e558e8 100644 --- a/types/ParseQuery.d.ts +++ b/types/ParseQuery.d.ts @@ -427,7 +427,7 @@ declare class ParseQuery { * @param value The value that the Parse.Object must contain. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - equalTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; + equalTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be not equal to the provided value. @@ -436,7 +436,7 @@ declare class ParseQuery { * @param value The value that must not be equalled. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - notEqualTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; + notEqualTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be less than the provided value. From 47eb227cb8f62eacf632269ef0a15e8833988369 Mon Sep 17 00:00:00 2001 From: Switt Kongdachalert Date: Fri, 6 Feb 2026 04:23:14 +0700 Subject: [PATCH 3/4] fix: regenerated types after forgotten commit to ParseQuery.ts --- src/ParseQuery.ts | 8 ++++---- types/ParseQuery.d.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ParseQuery.ts b/src/ParseQuery.ts index 91ece7e39..fbc02238d 100644 --- a/src/ParseQuery.ts +++ b/src/ParseQuery.ts @@ -1152,9 +1152,9 @@ class ParseQuery { key: K, value: | T['attributes'][K] - | (T['attributes'][K] extends ParseObject + | (NonNullable extends ParseObject ? Pointer - : T['attributes'][K] extends (infer E)[] + : NonNullable extends (infer E)[] ? E : never) ): this { @@ -1181,9 +1181,9 @@ class ParseQuery { key: K, value: | T['attributes'][K] - | (T['attributes'][K] extends ParseObject + | (NonNullable extends ParseObject ? Pointer - : T['attributes'][K] extends (infer E)[] + : NonNullable extends (infer E)[] ? E : never) ): this { diff --git a/types/ParseQuery.d.ts b/types/ParseQuery.d.ts index fa8e558e8..2706d8839 100644 --- a/types/ParseQuery.d.ts +++ b/types/ParseQuery.d.ts @@ -427,7 +427,7 @@ declare class ParseQuery { * @param value The value that the Parse.Object must contain. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - equalTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; + equalTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be not equal to the provided value. @@ -436,7 +436,7 @@ declare class ParseQuery { * @param value The value that must not be equalled. * @returns {Parse.Query} Returns the query, so you can chain this call. */ - notEqualTo(key: K, value: T['attributes'][K] | (T['attributes'][K] extends ParseObject ? Pointer : T['attributes'][K] extends (infer E)[] ? E : never)): this; + notEqualTo(key: K, value: T['attributes'][K] | (NonNullable extends ParseObject ? Pointer : NonNullable extends (infer E)[] ? E : never)): this; /** * Adds a constraint to the query that requires a particular key's value to * be less than the provided value. From c6e9fb5780c338dbdd505fb2db01a7a7878ae911 Mon Sep 17 00:00:00 2001 From: Switt Kongdachalert Date: Fri, 6 Feb 2026 05:38:42 +0700 Subject: [PATCH 4/4] fix: added negative case to provide type assertion safety for optional fields --- types/tests.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/types/tests.ts b/types/tests.ts index dd093b5b3..49f7349e0 100644 --- a/types/tests.ts +++ b/types/tests.ts @@ -1970,6 +1970,9 @@ function testQuery() { query.equalTo('attribute5', new AnotherSubClass()); // $ExpectType ParseQuery query.equalTo('attribute5', [new AnotherSubClass()]); + // Since there is no `$ExpectNotError` thing, this line is instead used to at least prove that there is no regression for type safety for `Array of object` fields + // $ExpectError + query.equalTo('attribute5', new MySubClass()); // Optional string[] (e.g. prop?: string[] ): allow matching a single element (array contains string), and allow matching the full array // $ExpectType ParseQuery