@@ -131,24 +131,31 @@ export type CheckMatchingArrayTypes<Result, NewResult> =
131131
132132type 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)
146+ : // Check if the override is on a embedded relation (array)
140147 New [ K ] extends any [ ]
141148 ? Row [ K ] extends any [ ]
142149 ? Array < Simplify < MergeDeep < NonNullable < New [ K ] [ number ] > , NonNullable < Row [ K ] [ number ] > > > >
143150 : New [ K ]
144- : // Check if both properties are objects omiting a potential null union
151+ : // Check if both properties are objects omitting a potential null union
145152 IsPlainObject < NonNullable < New [ K ] > > extends true
146153 ? IsPlainObject < NonNullable < Row [ K ] > > extends true
147154 ? // If they are, use the new override as source of truth for the optionality
148155 ContainsNull < New [ K ] > extends true
149- ? // If the override want to preserve optionality
156+ ? // If the override wants to preserve optionality
150157 Simplify < MergeDeep < NonNullable < New [ K ] > , NonNullable < Row [ K ] > > > | null
151- : // If the override want to enforce non-null result
158+ : // If the override wants to enforce non-null result
152159 Simplify < MergeDeep < New [ K ] , NonNullable < Row [ K ] > > >
153160 : New [ K ] // Override with New type if Row isn't an object
154161 : New [ K ] // Override primitives with New type
@@ -158,6 +165,15 @@ type MergeDeep<New, Row> = {
158165 : never
159166}
160167
168+ type MergeDeep < New , Row > = Simplify <
169+ MergeExplicit < New , Row > &
170+ // Intersection here is to restore dynamic keys into the merging result
171+ // eg:
172+ // {[key: number]: string}
173+ // or Record<string, number | null>
174+ ( string extends keyof Row ? { [ K : string ] : Row [ string ] } : { } )
175+ >
176+
161177// Helper to check if a type is a plain object (not an array)
162178type IsPlainObject < T > = T extends any [ ] ? false : T extends object ? true : false
163179
0 commit comments