From 3fbacceead308ac32d6a3345f6d22ba5f8ba351b Mon Sep 17 00:00:00 2001 From: Scott Trinh Date: Mon, 13 Nov 2023 20:26:20 -0500 Subject: [PATCH] wip Select function overload Type checks at this point, so going to use this as a savepoint --- integration-tests/lts/select.test.ts | 25 +++++++++++ packages/generate/src/syntax/select.ts | 60 ++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/integration-tests/lts/select.test.ts b/integration-tests/lts/select.test.ts index cec7831da..92c0664e1 100644 --- a/integration-tests/lts/select.test.ts +++ b/integration-tests/lts/select.test.ts @@ -99,6 +99,31 @@ describe("select", () => { ); }); + test("named tuple as free object", async () => { + const namedTuple = e.tuple({ + object: e.select(e.Hero, () => ({ limit: 1 })), + score: e.random(), + }); + + const query = e.select(namedTuple); + type Query = $infer; + tc.assert< + tc.IsExact< + Query, + { + object: { id: string }; + score: number; + }[] + > + >(true); + + const withShape = e.select(namedTuple, (q) => ({ + name: q.object.name, + score: q.score, + })); + type WithShape = $infer; + }); + test("named tuple to free object", async () => { const namedTuple = e.tuple({ object: e.select(e.Hero, () => ({ limit: 1 })), diff --git a/packages/generate/src/syntax/select.ts b/packages/generate/src/syntax/select.ts index 60371e7fc..d6fe5a829 100644 --- a/packages/generate/src/syntax/select.ts +++ b/packages/generate/src/syntax/select.ts @@ -35,6 +35,8 @@ import type { BaseType, ExclusiveTuple, orLiteralValue, + NamedTupleType, + $expr_TuplePath, } from "./typesystem"; import { @@ -111,7 +113,9 @@ export type exclusivesToFilterSingle = : orLiteralValue; }; }[number]; -export type SelectModifiers = { +export type SelectModifiers< + T extends ObjectType | NamedTupleType = ObjectType +> = { // export type SelectModifiers = { filter?: SelectFilterExpression; filter_single?: // | Partial< @@ -143,7 +147,9 @@ export type SelectModifiers = { // : never // : never; // }>) - exclusivesToFilterSingle | SelectFilterExpression; + T extends ObjectType + ? exclusivesToFilterSingle | SelectFilterExpression + : never; // | (ObjectType extends T // ? unknown @@ -368,7 +374,7 @@ export type InferOffsetLimitCardinality< // Modifiers // >; export type ComputeSelectCardinality< - Expr extends ObjectTypeExpression, + Expr extends ObjectTypeExpression | TypeSet, Modifiers extends UnknownSelectModifiers > = InferOffsetLimitCardinality< undefined extends Modifiers["filter_single"] @@ -780,6 +786,17 @@ export type objectTypeToSelectShape = : any; }> & { [k: string]: unknown }; +export type namedTupleTypeToSelectShape< + T extends NamedTupleType = NamedTupleType +> = Partial<{ + [k in keyof T["__shape__"]]: T["__shape__"][k] extends ObjectType + ? + | boolean + | TypeSet, Cardinality.One> + : boolean | TypeSet; +}> & + Record; + // incorporate __shape__ (computeds) on selection shapes // this works but a major rewrite of setToTsType is required // to incorporate __shape__-based selection shapes into @@ -879,6 +896,43 @@ export function select( export function select( expr: Expr ): $expr_Select>; +export function select< + Expr extends TypeSet, + RawShape extends namedTupleTypeToSelectShape, + Shape extends RawShape & SelectModifiers, + Modifiers extends UnknownSelectModifiers = Pick +>( + expr: Expr, + shape: ( + scope: $expr_TuplePath + ) => Readonly +): $expr_Select<{ + __element__: ObjectType< + `std::FreeObject`, + { + [k in keyof Expr["__element__"]["__shape__"]]: Expr["__element__"]["__shape__"][k] extends ObjectType + ? LinkDesc< + Expr["__element__"]["__shape__"][k], + Cardinality.One, + Record, + false, + true, + true, + false + > + : PropertyDesc< + Expr["__element__"]["__shape__"][k], + Cardinality.One, + false, + true, + true, + false + >; + }, + Omit, SelectModifierNames> + >; + __cardinality__: ComputeSelectCardinality; +}>; export function select< Expr extends ObjectTypeExpression, Shape extends objectTypeToSelectShape &