ResultTypeFromSelect
type ResultTypeFromSelect<TSelectObject> = IsAny<TSelectObject> extends true ? any : IsTrueRef<TSelectObject> extends true ? ExtractDirectSelectRef<TSelectObject> : WithoutRefBrand<Prettify<{ [K in keyof TSelectObject]: NeedsExtraction<TSelectObject[K]> extends true ? ExtractExpressionType<TSelectObject[K]> : TSelectObject[K] extends ToArrayWrapper<infer T> ? T[] : TSelectObject[K] extends ConcatToArrayWrapper<any> ? string : TSelectObject[K] extends MaterializeWrapper<infer T, infer IsSingle> ? IsSingle extends true ? (...) | (...) : (...)[] : (...)[(...)] extends { __brand: ...; _result?: ... } ? ResultTypeFromCaseWhen<(...)> : (...) extends (...) ? (...) : (...) }>>;Defined in: packages/db/src/query/builder/types.ts:413
ResultTypeFromSelect - Infers the result type from a select object
This complex type transforms the input to select() into the actual TypeScript
type that the query will return. It handles all the different kinds of values
that can appear in a select clause:
Ref/RefProxy Extraction:
RefProxy<T>→T: Extracts the underlying typeRef<T> | undefined→T | undefined: Preserves optionalityRef<T> | null→T | null: Preserves nullability
Expression Types:
BasicExpression<T>→T: Function results likeupper()→stringAggregate<T>→T: Aggregation results likecount()→number
JavaScript Literals (pass through as-is):
string→string: String literals remain stringsnumber→number: Numeric literals remain numbersboolean→boolean: Boolean literals remain booleansnull→null: Explicit null remains nullundefined→undefined: Direct undefined values
Nested Objects (recursive):
- Plain objects are recursively processed to handle nested projections
- RefProxy objects are detected and their types extracted
Example transformation:
// Input:
{ id: Ref<number>, name: Ref<string>, status: 'active', count: 42, profile: { bio: Ref<string> } }
// Output:
{ id: number, name: string, status: 'active', count: 42, profile: { bio: string } }Type Parameters
TSelectObject
TSelectObject