Skip to content

Commit a84a1ca

Browse files
ymc9Copilot
andauthored
fix: nested select result typing, simplifying ORM query result types (#92)
* fix: nested select result typing, simplifying ORM query result types * Update packages/runtime/src/utils/type-utils.ts Co-authored-by: Copilot <[email protected]> * update --------- Co-authored-by: Copilot <[email protected]>
1 parent 85d8c5d commit a84a1ca

File tree

4 files changed

+85
-28
lines changed

4 files changed

+85
-28
lines changed

packages/runtime/src/client/contract.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Decimal } from 'decimal.js';
22
import { type GetModels, type ProcedureDef, type SchemaDef } from '../schema';
33
import type { AuthType } from '../schema/auth';
4-
import type { OrUndefinedIf, UnwrapTuplePromises } from '../utils/type-utils';
4+
import type { OrUndefinedIf, Simplify, UnwrapTuplePromises } from '../utils/type-utils';
55
import type { TRANSACTION_UNSUPPORTED_METHODS } from './constants';
66
import type {
77
AggregateArgs,
@@ -299,7 +299,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
299299
*/
300300
findMany<T extends FindArgs<Schema, Model, true>>(
301301
args?: SelectSubset<T, FindArgs<Schema, Model, true>>,
302-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>[]>;
302+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>[]>;
303303

304304
/**
305305
* Returns a uniquely identified entity.
@@ -309,7 +309,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
309309
*/
310310
findUnique<T extends FindUniqueArgs<Schema, Model>>(
311311
args?: SelectSubset<T, FindUniqueArgs<Schema, Model>>,
312-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T> | null>;
312+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>> | null>;
313313

314314
/**
315315
* Returns a uniquely identified entity or throws `NotFoundError` if not found.
@@ -319,7 +319,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
319319
*/
320320
findUniqueOrThrow<T extends FindUniqueArgs<Schema, Model>>(
321321
args?: SelectSubset<T, FindUniqueArgs<Schema, Model>>,
322-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>>;
322+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>>;
323323

324324
/**
325325
* Returns the first entity.
@@ -329,7 +329,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
329329
*/
330330
findFirst<T extends FindArgs<Schema, Model, true>>(
331331
args?: SelectSubset<T, FindArgs<Schema, Model, true>>,
332-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T> | null>;
332+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>> | null>;
333333

334334
/**
335335
* Returns the first entity or throws `NotFoundError` if not found.
@@ -339,7 +339,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
339339
*/
340340
findFirstOrThrow<T extends FindArgs<Schema, Model, true>>(
341341
args?: SelectSubset<T, FindArgs<Schema, Model, true>>,
342-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>>;
342+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>>;
343343

344344
/**
345345
* Creates a new entity.
@@ -395,7 +395,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
395395
*/
396396
create<T extends CreateArgs<Schema, Model>>(
397397
args: SelectSubset<T, CreateArgs<Schema, Model>>,
398-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>>;
398+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>>;
399399

400400
/**
401401
* Creates multiple entities. Only scalar fields are allowed.
@@ -446,7 +446,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
446446
*/
447447
createManyAndReturn<T extends CreateManyAndReturnArgs<Schema, Model>>(
448448
args?: SelectSubset<T, CreateManyAndReturnArgs<Schema, Model>>,
449-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>[]>;
449+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>[]>;
450450

451451
/**
452452
* Updates a uniquely identified entity.
@@ -567,7 +567,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
567567
*/
568568
update<T extends UpdateArgs<Schema, Model>>(
569569
args: SelectSubset<T, UpdateArgs<Schema, Model>>,
570-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>>;
570+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>>;
571571

572572
/**
573573
* Updates multiple entities.
@@ -617,7 +617,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
617617
*/
618618
updateManyAndReturn<T extends UpdateManyAndReturnArgs<Schema, Model>>(
619619
args: Subset<T, UpdateManyAndReturnArgs<Schema, Model>>,
620-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>[]>;
620+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>[]>;
621621

622622
/**
623623
* Creates or updates an entity.
@@ -641,7 +641,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
641641
*/
642642
upsert<T extends UpsertArgs<Schema, Model>>(
643643
args: SelectSubset<T, UpsertArgs<Schema, Model>>,
644-
): ZenStackPromise<Schema, ModelResult<Schema, Model, T>>;
644+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model, T>>>;
645645

646646
/**
647647
* Deletes a uniquely identifiable entity.
@@ -664,7 +664,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
664664
*/
665665
delete<T extends DeleteArgs<Schema, Model>>(
666666
args: SelectSubset<T, DeleteArgs<Schema, Model>>,
667-
): ZenStackPromise<Schema, ModelResult<Schema, Model>>;
667+
): ZenStackPromise<Schema, Simplify<ModelResult<Schema, Model>>>;
668668

669669
/**
670670
* Deletes multiple entities.
@@ -709,7 +709,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
709709
*/
710710
count<T extends CountArgs<Schema, Model>>(
711711
args?: Subset<T, CountArgs<Schema, Model>>,
712-
): ZenStackPromise<Schema, CountResult<Schema, Model, T>>;
712+
): ZenStackPromise<Schema, Simplify<CountResult<Schema, Model, T>>>;
713713

714714
/**
715715
* Aggregates rows.
@@ -730,7 +730,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
730730
*/
731731
aggregate<T extends AggregateArgs<Schema, Model>>(
732732
args: Subset<T, AggregateArgs<Schema, Model>>,
733-
): ZenStackPromise<Schema, AggregateResult<Schema, Model, T>>;
733+
): ZenStackPromise<Schema, Simplify<AggregateResult<Schema, Model, T>>>;
734734

735735
/**
736736
* Groups rows by columns.
@@ -766,7 +766,7 @@ export interface ModelOperations<Schema extends SchemaDef, Model extends GetMode
766766
*/
767767
groupBy<T extends GroupByArgs<Schema, Model>>(
768768
args: Subset<T, GroupByArgs<Schema, Model>>,
769-
): ZenStackPromise<Schema, GroupByResult<Schema, Model, T>>;
769+
): ZenStackPromise<Schema, Simplify<GroupByResult<Schema, Model, T>>>;
770770
}
771771

772772
//#endregion

packages/runtime/src/client/crud-types.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,21 @@ type ModelSelectResult<Schema extends SchemaDef, Model extends GetModels<Schema>
7777
RelationFieldType<Schema, Model, Key>,
7878
FieldIsArray<Schema, Model, Key>
7979
>
80-
? ModelResult<
81-
Schema,
82-
RelationFieldType<Schema, Model, Key>,
83-
Select[Key],
84-
FieldIsOptional<Schema, Model, Key>,
85-
FieldIsArray<Schema, Model, Key>
86-
>
80+
? 'select' extends keyof Select[Key]
81+
? ModelResult<
82+
Schema,
83+
RelationFieldType<Schema, Model, Key>,
84+
Pick<Select[Key], 'select'>,
85+
FieldIsOptional<Schema, Model, Key>,
86+
FieldIsArray<Schema, Model, Key>
87+
>
88+
: ModelResult<
89+
Schema,
90+
RelationFieldType<Schema, Model, Key>,
91+
Pick<Select[Key], 'include' | 'omit'>,
92+
FieldIsOptional<Schema, Model, Key>,
93+
FieldIsArray<Schema, Model, Key>
94+
>
8795
: DefaultModelResult<
8896
Schema,
8997
RelationFieldType<Schema, Model, Key>,

packages/runtime/src/utils/type-utils.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ export type NullableIf<T, Condition extends boolean> = Condition extends true ?
66

77
export type PartialRecord<K extends string | number | symbol, T> = Partial<Record<K, T>>;
88

9+
type _Preserve = Date | Function | Decimal | Uint8Array;
10+
type _Depth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
11+
export type Simplify<T, D extends number = 6> = D extends 0
12+
? T
13+
: T extends object
14+
? T extends _Preserve
15+
? T
16+
: { [K in keyof T]: Simplify<T[K], _Depth[D]> } & {}
17+
: T;
18+
919
export type WrapType<T, Optional = false, Array = false> = Optional extends true
1020
? T | null
1121
: Array extends true
@@ -24,17 +34,17 @@ export type MapBaseType<T> = T extends 'String'
2434
? Decimal
2535
: T extends 'DateTime'
2636
? Date
27-
: T extends 'Json'
28-
? JsonValue
29-
: unknown;
37+
: T extends 'Bytes'
38+
? Uint8Array
39+
: T extends 'Json'
40+
? JsonValue
41+
: unknown;
3042

3143
export type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
3244

3345
export type JsonObject = { [key: string]: JsonValue };
3446
export type JsonArray = Array<JsonValue>;
3547

36-
export type Simplify<T> = { [Key in keyof T]: T[Key] } & {};
37-
3848
export function call(code: string) {
3949
return { code };
4050
}

packages/runtime/test/typing/verify-typing.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import SQLite from 'better-sqlite3';
12
import { ZenStackClient } from '../../dist';
23
import { Role } from './models';
34
import { schema } from './schema';
4-
import SQLite from 'better-sqlite3';
55

66
const client = new ZenStackClient(schema, {
77
dialectConfig: {
@@ -147,6 +147,45 @@ async function find() {
147147
},
148148
})
149149
).profile?.region?.city;
150+
151+
(
152+
await client.user.findFirstOrThrow({
153+
select: {
154+
posts: {
155+
where: { title: 'Foo' },
156+
select: {
157+
author: {
158+
select: {
159+
id: true,
160+
},
161+
},
162+
},
163+
},
164+
},
165+
})
166+
).posts[0]?.author?.id;
167+
168+
const u = await client.user.findFirstOrThrow({
169+
select: {
170+
posts: {
171+
where: { title: 'Foo' },
172+
select: {
173+
author: {
174+
include: {
175+
profile: true,
176+
},
177+
omit: {
178+
email: true,
179+
},
180+
},
181+
},
182+
},
183+
},
184+
});
185+
console.log(u.posts[0]?.author?.profile?.age);
186+
console.log(u.posts[0]?.author?.role);
187+
// @ts-expect-error
188+
console.log(u.posts[0]?.author?.email);
150189
}
151190

152191
async function create() {

0 commit comments

Comments
 (0)