Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.

Commit 6b26db4

Browse files
committed
fix(types): allow merge Record and litteral object
1 parent 50eb37c commit 6b26db4

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

src/types.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,33 +131,39 @@ export type CheckMatchingArrayTypes<Result, NewResult> =
131131

132132
type Simplify<T> = T extends object ? { [K in keyof T]: T[K] } : T
133133

134-
type MergeDeep<New, Row> = {
135-
[K in keyof New | keyof Row]: K extends keyof New
134+
// Extract only explicit (non-index-signature) keys.
135+
type ExplicitKeys<T> = {
136+
[K in keyof T]: string extends K ? never : K
137+
}[keyof T]
138+
139+
type MergeExplicit<New, Row> = {
140+
// We merge all the explicit keys which allows merge and override of types like
141+
// { [key: string]: unknown } and { someSpecificKey: boolean }
142+
[K in ExplicitKeys<New> | ExplicitKeys<Row>]: K extends keyof New
136143
? K extends keyof Row
137144
? Row[K] extends SelectQueryError<string>
138145
? New[K]
139-
: // Check if the override is on a embeded relation (array)
140-
New[K] extends any[]
146+
: New[K] extends any[]
141147
? Row[K] extends any[]
142148
? Array<Simplify<MergeDeep<NonNullable<New[K][number]>, NonNullable<Row[K][number]>>>>
143149
: New[K]
144-
: // Check if both properties are objects omiting a potential null union
145-
IsPlainObject<NonNullable<New[K]>> extends true
150+
: IsPlainObject<NonNullable<New[K]>> extends true
146151
? IsPlainObject<NonNullable<Row[K]>> extends true
147-
? // If they are, use the new override as source of truth for the optionality
148-
ContainsNull<New[K]> extends true
149-
? // If the override want to preserve optionality
150-
Simplify<MergeDeep<NonNullable<New[K]>, NonNullable<Row[K]>>> | null
151-
: // If the override want to enforce non-null result
152-
Simplify<MergeDeep<New[K], NonNullable<Row[K]>>>
153-
: New[K] // Override with New type if Row isn't an object
154-
: New[K] // Override primitives with New type
155-
: New[K] // Add new properties from New
152+
? ContainsNull<New[K]> extends true
153+
? Simplify<MergeDeep<NonNullable<New[K]>, NonNullable<Row[K]>>> | null
154+
: Simplify<MergeDeep<New[K], NonNullable<Row[K]>>>
155+
: New[K]
156+
: New[K]
157+
: New[K]
156158
: K extends keyof Row
157-
? Row[K] // Keep existing properties not in New
159+
? Row[K]
158160
: never
159161
}
160162

163+
type MergeDeep<New, Row> = Simplify<
164+
MergeExplicit<New, Row> & (string extends keyof Row ? { [K: string]: Row[string] } : {})
165+
>
166+
161167
// Helper to check if a type is a plain object (not an array)
162168
type IsPlainObject<T> = T extends any[] ? false : T extends object ? true : false
163169

test/override-types.test-d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,10 @@ const postgrest = new PostgrestClient<Database>(REST_URL)
375375
baz: number
376376
}
377377
en: 'ONE' | 'TWO' | 'THREE'
378-
record: { baz: 'foo' }
378+
record: {
379+
[x: string]: Json | undefined
380+
baz: 'foo'
381+
}
379382
}
380383
age_range: unknown
381384
catchphrase: unknown

0 commit comments

Comments
 (0)