@@ -159,17 +159,19 @@ function looseEqual(a: unknown, b: unknown): boolean {
159159 if ( typeof a === "bigint" && typeof b === "bigint" ) return a === b ;
160160 if ( typeof a === "string" && typeof b === "string" ) return a === b ;
161161 if ( typeof a === "boolean" && typeof b === "boolean" ) return a === b ;
162- // Cross-type numeric comparison
163- if ( typeof a === "number" && typeof b === "bigint" ) return a === Number ( b ) ;
164- if ( typeof a === "bigint" && typeof b === "number" ) return Number ( a ) === b ;
162+ // Cross-type numeric: prefer bigint when safe to avoid precision loss
163+ if ( typeof a === "number" && typeof b === "bigint" ) return Number . isSafeInteger ( a ) ? BigInt ( a ) === b : a === Number ( b ) ;
164+ if ( typeof a === "bigint" && typeof b === "number" ) return Number . isSafeInteger ( b ) ? a === BigInt ( b ) : Number ( a ) === b ;
165165 return a === b ;
166166}
167167
168168function compare ( a : unknown , b : unknown ) : number {
169169 if ( typeof a === "number" && typeof b === "number" ) return a - b ;
170170 if ( typeof a === "bigint" && typeof b === "bigint" ) return a < b ? - 1 : a > b ? 1 : 0 ;
171171 if ( typeof a === "string" && typeof b === "string" ) return a . localeCompare ( b ) ;
172- // Cross-type: coerce to number
172+ // Cross-type bigint/number: prefer bigint when safe
173+ if ( typeof a === "bigint" && typeof b === "number" && Number . isSafeInteger ( b ) ) { const bb = BigInt ( b ) ; return a < bb ? - 1 : a > bb ? 1 : 0 ; }
174+ if ( typeof a === "number" && typeof b === "bigint" && Number . isSafeInteger ( a ) ) { const ab = BigInt ( a ) ; return ab < b ? - 1 : ab > b ? 1 : 0 ; }
173175 return toNumber ( a ) - toNumber ( b ) ;
174176}
175177
@@ -188,7 +190,8 @@ function matchLike(value: string, pattern: string): boolean {
188190function castValue ( val : unknown , targetType : string ) : unknown {
189191 if ( val === null ) return null ;
190192 const t = targetType . toLowerCase ( ) ;
191- if ( t === "int" || t === "integer" || t === "bigint" ) return Math . trunc ( toNumber ( val ) ) ;
193+ if ( t === "bigint" ) return BigInt ( Math . trunc ( toNumber ( val ) ) ) ;
194+ if ( t === "int" || t === "integer" ) return Math . trunc ( toNumber ( val ) ) ;
192195 if ( t === "float" || t === "double" || t === "real" || t === "decimal" || t === "numeric" ) return toNumber ( val ) ;
193196 if ( t === "text" || t === "varchar" || t === "string" || t === "char" ) return String ( val ) ;
194197 if ( t === "bool" || t === "boolean" ) return isTruthy ( val ) ;
0 commit comments