Skip to content

Commit

Permalink
Require opt-in to prevent it being a breaking change
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonF committed Sep 3, 2024
1 parent 7131057 commit b4dfe85
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 16 deletions.
36 changes: 20 additions & 16 deletions integration-tests/lts/select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import * as $ from "../../packages/generate/src/syntax/reflection";
import e, { type $infer } from "./dbschema/edgeql-js";
import { setupTests, teardownTests, tc, type TestData } from "./setupTeardown";

declare module "./dbschema/edgeql-js/typesystem" {
export interface SetTypesystemOptions {
future: {
polymorphismAsDiscriminatedUnions: true;
};
}
}

let client: edgedb.Client;
let data: TestData;

Expand Down Expand Up @@ -239,7 +247,7 @@ describe("select", () => {
assert.deepEqual(query.__element__.__kind__, $.TypeKind.object);
assert.equal(query.__element__.__name__, "default::Person");

type result = $.BaseTypeToTsType<(typeof query)["__element__"]>;
type result = $infer<typeof query>[number];
tc.assert<
tc.IsExact<
result,
Expand Down Expand Up @@ -294,21 +302,17 @@ describe("select", () => {
}),
}));

type q = $.setToTsType<typeof q>;
tc.assert<
tc.IsExact<
q,
({
id: string;
} & (
| { __typename: "default::Hero"; secret_identity: string | null }
| {
__typename: "default::Villain";
nemesis: { id: string; computable: 1234 } | null;
}
))[]
>
>(true);
type actual = $infer<typeof q>[number];
type expected = {
id: string;
} & (
| { __typename: "default::Hero"; secret_identity: string | null }
| {
__typename: "default::Villain";
nemesis: { id: string; computable: 1234 } | null;
}
);
tc.assert<tc.IsExact<actual, expected>>(true);
});

test("parent type props in polymorphic", () => {
Expand Down
64 changes: 64 additions & 0 deletions packages/generate/src/syntax/typesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ import type { cardutil } from "./cardinality";
import type { Range, MultiRange } from "edgedb";
import type { $Shape, normaliseShape } from "./select";

/**
* Use declaration merging to set the {@link TypesystemOptions} via this
*/
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface SetTypesystemOptions {}

export type TypesystemOptions = {
future: {
/**
* Opt-in to the new discriminated union functionality for polymorphism.
*/
polymorphismAsDiscriminatedUnions: SetTypesystemOptions extends {
future: { polymorphismAsDiscriminatedUnions: true };
}
? true
: false;
};
};

//////////////////
// BASETYPE
//////////////////
Expand Down Expand Up @@ -372,6 +391,51 @@ export type $expr_PolyShapeElement<
};

export type computeObjectShape<
Pointers extends ObjectTypePointers,
Shape,
TypeName extends string = string,
> = TypesystemOptions["future"]["polymorphismAsDiscriminatedUnions"] extends true
? computeObjectShapeNew<Pointers, Shape, TypeName>
: computeObjectShapeLegacy<Pointers, Shape, TypeName>;

type computeObjectShapeLegacy<
Pointers extends ObjectTypePointers,
Shape,
TypeName extends string,
> = typeutil.flatten<
keyof Shape extends never
? { id: string }
: typeutil.stripNever<{
[k in keyof Shape]: Shape[k] extends $expr_PolyShapeElement<
infer PolyType,
infer ShapeEl
>
? [k] extends [keyof PolyType["__element__"]["__pointers__"]]
? shapeElementToTs<
PolyType["__element__"]["__pointers__"][k],
ShapeEl,
k extends "__type__" ? TypeName : null
> | null
: never
: Shape[k] extends TypeSet
? [k] extends [keyof Pointers]
? Shape[k]["__cardinality__"] extends cardutil.assignable<
Pointers[k]["cardinality"]
>
? setToTsType<Shape[k]>
: never
: setToTsType<Shape[k]>
: [k] extends [keyof Pointers]
? shapeElementToTs<
Pointers[k],
Shape[k],
k extends "__type__" ? TypeName : null
>
: never;
}>
>;

type computeObjectShapeNew<
Pointers extends ObjectTypePointers,
Shape,
TypeName extends string,
Expand Down

0 comments on commit b4dfe85

Please sign in to comment.