@prisma/ts-builders 6.13.0-dev.2 → 6.13.0-dev.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import { TypeBuilder } from './TypeBuilder';
2
+ import { Writer } from './Writer';
3
+ export declare class ConditionalType extends TypeBuilder {
4
+ #private;
5
+ needsParenthesisInUnion: boolean;
6
+ needsParenthesisInIntersection: boolean;
7
+ constructor(checkType: TypeBuilder, extendsType: TypeBuilder, trueType: TypeBuilder, falseType: TypeBuilder);
8
+ write(writer: Writer): void;
9
+ }
10
+ declare class ConditionalTypeBuilder {
11
+ check(checkType: TypeBuilder): ConditionalTypeBuilderWithCheckType;
12
+ }
13
+ declare class ConditionalTypeBuilderWithCheckType {
14
+ #private;
15
+ constructor(checkType: TypeBuilder);
16
+ extends(extendsType: TypeBuilder): ConditionalTypeBuilderWithExtendsType;
17
+ }
18
+ declare class ConditionalTypeBuilderWithExtendsType {
19
+ #private;
20
+ constructor(checkType: TypeBuilder, extendsType: TypeBuilder);
21
+ then(trueType: TypeBuilder): ConditionalTypeBuilderWithTrueType;
22
+ }
23
+ declare class ConditionalTypeBuilderWithTrueType {
24
+ #private;
25
+ constructor(checkType: TypeBuilder, extendsType: TypeBuilder, trueType: TypeBuilder);
26
+ else(falseType: TypeBuilder): ConditionalType;
27
+ }
28
+ export declare function conditionalType(): ConditionalTypeBuilder;
29
+ export {};
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var ConditionalType_exports = {};
20
+ __export(ConditionalType_exports, {
21
+ ConditionalType: () => ConditionalType,
22
+ conditionalType: () => conditionalType
23
+ });
24
+ module.exports = __toCommonJS(ConditionalType_exports);
25
+ var import_TypeBuilder = require("./TypeBuilder");
26
+ class ConditionalType extends import_TypeBuilder.TypeBuilder {
27
+ needsParenthesisInUnion = true;
28
+ needsParenthesisInIntersection = true;
29
+ #checkType;
30
+ #extendsType;
31
+ #trueType;
32
+ #falseType;
33
+ constructor(checkType, extendsType, trueType, falseType) {
34
+ super();
35
+ this.#checkType = checkType;
36
+ this.#extendsType = extendsType;
37
+ this.#trueType = trueType;
38
+ this.#falseType = falseType;
39
+ }
40
+ write(writer) {
41
+ writer.write(this.#checkType);
42
+ writer.write(" extends ");
43
+ writer.write(this.#extendsType);
44
+ writer.write(" ? ");
45
+ writer.write(this.#trueType);
46
+ writer.write(" : ");
47
+ writer.write(this.#falseType);
48
+ }
49
+ }
50
+ class ConditionalTypeBuilder {
51
+ check(checkType) {
52
+ return new ConditionalTypeBuilderWithCheckType(checkType);
53
+ }
54
+ }
55
+ class ConditionalTypeBuilderWithCheckType {
56
+ #checkType;
57
+ constructor(checkType) {
58
+ this.#checkType = checkType;
59
+ }
60
+ extends(extendsType) {
61
+ return new ConditionalTypeBuilderWithExtendsType(this.#checkType, extendsType);
62
+ }
63
+ }
64
+ class ConditionalTypeBuilderWithExtendsType {
65
+ #checkType;
66
+ #extendsType;
67
+ constructor(checkType, extendsType) {
68
+ this.#checkType = checkType;
69
+ this.#extendsType = extendsType;
70
+ }
71
+ then(trueType) {
72
+ return new ConditionalTypeBuilderWithTrueType(this.#checkType, this.#extendsType, trueType);
73
+ }
74
+ }
75
+ class ConditionalTypeBuilderWithTrueType {
76
+ #checkType;
77
+ #extendsType;
78
+ #trueType;
79
+ constructor(checkType, extendsType, trueType) {
80
+ this.#checkType = checkType;
81
+ this.#extendsType = extendsType;
82
+ this.#trueType = trueType;
83
+ }
84
+ else(falseType) {
85
+ return new ConditionalType(this.#checkType, this.#extendsType, this.#trueType, falseType);
86
+ }
87
+ }
88
+ function conditionalType() {
89
+ return new ConditionalTypeBuilder();
90
+ }
91
+ // Annotate the CommonJS export names for ESM import in node:
92
+ 0 && (module.exports = {
93
+ ConditionalType,
94
+ conditionalType
95
+ });
@@ -0,0 +1,70 @@
1
+ import { TypeBuilder } from "./TypeBuilder";
2
+ class ConditionalType extends TypeBuilder {
3
+ needsParenthesisInUnion = true;
4
+ needsParenthesisInIntersection = true;
5
+ #checkType;
6
+ #extendsType;
7
+ #trueType;
8
+ #falseType;
9
+ constructor(checkType, extendsType, trueType, falseType) {
10
+ super();
11
+ this.#checkType = checkType;
12
+ this.#extendsType = extendsType;
13
+ this.#trueType = trueType;
14
+ this.#falseType = falseType;
15
+ }
16
+ write(writer) {
17
+ writer.write(this.#checkType);
18
+ writer.write(" extends ");
19
+ writer.write(this.#extendsType);
20
+ writer.write(" ? ");
21
+ writer.write(this.#trueType);
22
+ writer.write(" : ");
23
+ writer.write(this.#falseType);
24
+ }
25
+ }
26
+ class ConditionalTypeBuilder {
27
+ check(checkType) {
28
+ return new ConditionalTypeBuilderWithCheckType(checkType);
29
+ }
30
+ }
31
+ class ConditionalTypeBuilderWithCheckType {
32
+ #checkType;
33
+ constructor(checkType) {
34
+ this.#checkType = checkType;
35
+ }
36
+ extends(extendsType) {
37
+ return new ConditionalTypeBuilderWithExtendsType(this.#checkType, extendsType);
38
+ }
39
+ }
40
+ class ConditionalTypeBuilderWithExtendsType {
41
+ #checkType;
42
+ #extendsType;
43
+ constructor(checkType, extendsType) {
44
+ this.#checkType = checkType;
45
+ this.#extendsType = extendsType;
46
+ }
47
+ then(trueType) {
48
+ return new ConditionalTypeBuilderWithTrueType(this.#checkType, this.#extendsType, trueType);
49
+ }
50
+ }
51
+ class ConditionalTypeBuilderWithTrueType {
52
+ #checkType;
53
+ #extendsType;
54
+ #trueType;
55
+ constructor(checkType, extendsType, trueType) {
56
+ this.#checkType = checkType;
57
+ this.#extendsType = extendsType;
58
+ this.#trueType = trueType;
59
+ }
60
+ else(falseType) {
61
+ return new ConditionalType(this.#checkType, this.#extendsType, this.#trueType, falseType);
62
+ }
63
+ }
64
+ function conditionalType() {
65
+ return new ConditionalTypeBuilder();
66
+ }
67
+ export {
68
+ ConditionalType,
69
+ conditionalType
70
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_ArrayType = require("./ArrayType");
4
+ var import_ConditionalType = require("./ConditionalType");
5
+ var import_FunctionType = require("./FunctionType");
6
+ var import_IntersectionType = require("./IntersectionType");
7
+ var import_NamedType = require("./NamedType");
8
+ var import_ObjectType = require("./ObjectType");
9
+ var import_Parameter = require("./Parameter");
10
+ var import_Property = require("./Property");
11
+ var import_stringify = require("./stringify");
12
+ var import_UnionType = require("./UnionType");
13
+ const A = (0, import_NamedType.namedType)("A");
14
+ const B = (0, import_NamedType.namedType)("B");
15
+ const C = (0, import_NamedType.namedType)("C");
16
+ const D = (0, import_NamedType.namedType)("D");
17
+ (0, import_vitest.test)("basic conditional type", () => {
18
+ const conditional = (0, import_ConditionalType.conditionalType)().check(A).extends(B).then(C).else(D);
19
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"A extends B ? C : D"`);
20
+ });
21
+ (0, import_vitest.test)("with union type as check type", () => {
22
+ const union = (0, import_UnionType.unionType)(A).addVariant(B);
23
+ const conditional = (0, import_ConditionalType.conditionalType)().check(union).extends(C).then((0, import_NamedType.namedType)("true")).else((0, import_NamedType.namedType)("false"));
24
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"A | B extends C ? true : false"`);
25
+ });
26
+ (0, import_vitest.test)("with array type as extends type", () => {
27
+ const conditional = (0, import_ConditionalType.conditionalType)().check(A).extends((0, import_ArrayType.array)(B)).then((0, import_NamedType.namedType)("IsArray")).else((0, import_NamedType.namedType)("NotArray"));
28
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"A extends B[] ? IsArray : NotArray"`);
29
+ });
30
+ (0, import_vitest.test)("with object types", () => {
31
+ const objType = (0, import_ObjectType.objectType)().add((0, import_Property.property)("name", (0, import_NamedType.namedType)("string"))).add((0, import_Property.property)("age", (0, import_NamedType.namedType)("number")));
32
+ const conditional = (0, import_ConditionalType.conditionalType)().check(A).extends(objType).then((0, import_NamedType.namedType)("IsObject")).else((0, import_NamedType.namedType)("NotObject"));
33
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`
34
+ "A extends {
35
+ name: string
36
+ age: number
37
+ } ? IsObject : NotObject"
38
+ `);
39
+ });
40
+ (0, import_vitest.test)("with function types", () => {
41
+ const funcType = (0, import_FunctionType.functionType)().addParameter((0, import_Parameter.parameter)("x", (0, import_NamedType.namedType)("string"))).setReturnType((0, import_NamedType.namedType)("number"));
42
+ const conditional = (0, import_ConditionalType.conditionalType)().check(A).extends(funcType).then((0, import_NamedType.namedType)("IsFunction")).else((0, import_NamedType.namedType)("NotFunction"));
43
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"A extends (x: string) => number ? IsFunction : NotFunction"`);
44
+ });
45
+ (0, import_vitest.test)("nested conditional types", () => {
46
+ const innerConditional = (0, import_ConditionalType.conditionalType)().check(A).extends(B).then(C).else(D);
47
+ const outerConditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("string")).then(innerConditional).else((0, import_NamedType.namedType)("never"));
48
+ (0, import_vitest.expect)((0, import_stringify.stringify)(outerConditional)).toMatchInlineSnapshot(`"T extends string ? A extends B ? C : D : never"`);
49
+ });
50
+ (0, import_vitest.test)("with generic types", () => {
51
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("U")).then((0, import_NamedType.namedType)("T")).else((0, import_NamedType.namedType)("never"));
52
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends U ? T : never"`);
53
+ });
54
+ (0, import_vitest.test)("complex real-world example", () => {
55
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_ArrayType.array)((0, import_NamedType.namedType)("any"))).then((0, import_NamedType.namedType)("T[0]")).else((0, import_NamedType.namedType)("T"));
56
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends any[] ? T[0] : T"`);
57
+ });
58
+ (0, import_vitest.test)("with literal types", () => {
59
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)('"foo"')).then((0, import_NamedType.namedType)("true")).else((0, import_NamedType.namedType)("false"));
60
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends "foo" ? true : false"`);
61
+ });
62
+ (0, import_vitest.test)("with intersection types", () => {
63
+ const intersection = (0, import_IntersectionType.intersectionType)(A).addType(B);
64
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends(intersection).then((0, import_NamedType.namedType)("HasBoth")).else((0, import_NamedType.namedType)("NotBoth"));
65
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends A & B ? HasBoth : NotBoth"`);
66
+ });
67
+ (0, import_vitest.test)("with tuple types", () => {
68
+ const tupleType = (0, import_NamedType.namedType)("[string, number]");
69
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends(tupleType).then((0, import_NamedType.namedType)("IsTuple")).else((0, import_NamedType.namedType)("NotTuple"));
70
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends [string, number] ? IsTuple : NotTuple"`);
71
+ });
72
+ (0, import_vitest.test)("with keyof type", () => {
73
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("K")).extends((0, import_NamedType.namedType)("keyof T")).then((0, import_NamedType.namedType)("K")).else((0, import_NamedType.namedType)("never"));
74
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"K extends keyof T ? K : never"`);
75
+ });
76
+ (0, import_vitest.test)("with never type", () => {
77
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("never")).then((0, import_NamedType.namedType)("NeverReached")).else((0, import_NamedType.namedType)("NotNever"));
78
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends never ? NeverReached : NotNever"`);
79
+ });
80
+ (0, import_vitest.test)("with unknown type", () => {
81
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("unknown")).then((0, import_NamedType.namedType)("AlwaysTrue")).else((0, import_NamedType.namedType)("NeverReached"));
82
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends unknown ? AlwaysTrue : NeverReached"`);
83
+ });
84
+ (0, import_vitest.test)("with any type", () => {
85
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("any")).extends((0, import_NamedType.namedType)("T")).then((0, import_NamedType.namedType)("AnyExtendsT")).else((0, import_NamedType.namedType)("NotExtends"));
86
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"any extends T ? AnyExtendsT : NotExtends"`);
87
+ });
88
+ (0, import_vitest.test)("deeply nested conditional types", () => {
89
+ const deeplyNested = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("string")).then(
90
+ (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("U")).extends((0, import_NamedType.namedType)("number")).then(
91
+ (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("V")).extends((0, import_NamedType.namedType)("boolean")).then((0, import_NamedType.namedType)("AllMatch")).else((0, import_NamedType.namedType)("VNotBoolean"))
92
+ ).else((0, import_NamedType.namedType)("UNotNumber"))
93
+ ).else((0, import_NamedType.namedType)("TNotString"));
94
+ (0, import_vitest.expect)((0, import_stringify.stringify)(deeplyNested)).toMatchInlineSnapshot(
95
+ `"T extends string ? U extends number ? V extends boolean ? AllMatch : VNotBoolean : UNotNumber : TNotString"`
96
+ );
97
+ });
98
+ (0, import_vitest.test)("with template literal types", () => {
99
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("`prefix_${string}`")).then((0, import_NamedType.namedType)("HasPrefix")).else((0, import_NamedType.namedType)("NoPrefix"));
100
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends \`prefix_\${string}\` ? HasPrefix : NoPrefix"`);
101
+ });
102
+ (0, import_vitest.test)("with infer keyword", () => {
103
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("Promise<infer U>")).then((0, import_NamedType.namedType)("U")).else((0, import_NamedType.namedType)("never"));
104
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T extends Promise<infer U> ? U : never"`);
105
+ });
106
+ (0, import_vitest.test)("conditional type in union", () => {
107
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("string")).then((0, import_NamedType.namedType)("A")).else((0, import_NamedType.namedType)("B"));
108
+ const union = (0, import_UnionType.unionType)(conditional).addVariant((0, import_NamedType.namedType)("C"));
109
+ (0, import_vitest.expect)((0, import_stringify.stringify)(union)).toMatchInlineSnapshot(`"(T extends string ? A : B) | C"`);
110
+ });
111
+ (0, import_vitest.test)("with mapped type notation", () => {
112
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T[K]")).extends((0, import_NamedType.namedType)("Function")).then((0, import_NamedType.namedType)("K")).else((0, import_NamedType.namedType)("never"));
113
+ (0, import_vitest.expect)((0, import_stringify.stringify)(conditional)).toMatchInlineSnapshot(`"T[K] extends Function ? K : never"`);
114
+ });
@@ -0,0 +1,113 @@
1
+ import { expect, test } from "vitest";
2
+ import { array } from "./ArrayType";
3
+ import { conditionalType } from "./ConditionalType";
4
+ import { functionType } from "./FunctionType";
5
+ import { intersectionType } from "./IntersectionType";
6
+ import { namedType } from "./NamedType";
7
+ import { objectType } from "./ObjectType";
8
+ import { parameter } from "./Parameter";
9
+ import { property } from "./Property";
10
+ import { stringify } from "./stringify";
11
+ import { unionType } from "./UnionType";
12
+ const A = namedType("A");
13
+ const B = namedType("B");
14
+ const C = namedType("C");
15
+ const D = namedType("D");
16
+ test("basic conditional type", () => {
17
+ const conditional = conditionalType().check(A).extends(B).then(C).else(D);
18
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"A extends B ? C : D"`);
19
+ });
20
+ test("with union type as check type", () => {
21
+ const union = unionType(A).addVariant(B);
22
+ const conditional = conditionalType().check(union).extends(C).then(namedType("true")).else(namedType("false"));
23
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"A | B extends C ? true : false"`);
24
+ });
25
+ test("with array type as extends type", () => {
26
+ const conditional = conditionalType().check(A).extends(array(B)).then(namedType("IsArray")).else(namedType("NotArray"));
27
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"A extends B[] ? IsArray : NotArray"`);
28
+ });
29
+ test("with object types", () => {
30
+ const objType = objectType().add(property("name", namedType("string"))).add(property("age", namedType("number")));
31
+ const conditional = conditionalType().check(A).extends(objType).then(namedType("IsObject")).else(namedType("NotObject"));
32
+ expect(stringify(conditional)).toMatchInlineSnapshot(`
33
+ "A extends {
34
+ name: string
35
+ age: number
36
+ } ? IsObject : NotObject"
37
+ `);
38
+ });
39
+ test("with function types", () => {
40
+ const funcType = functionType().addParameter(parameter("x", namedType("string"))).setReturnType(namedType("number"));
41
+ const conditional = conditionalType().check(A).extends(funcType).then(namedType("IsFunction")).else(namedType("NotFunction"));
42
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"A extends (x: string) => number ? IsFunction : NotFunction"`);
43
+ });
44
+ test("nested conditional types", () => {
45
+ const innerConditional = conditionalType().check(A).extends(B).then(C).else(D);
46
+ const outerConditional = conditionalType().check(namedType("T")).extends(namedType("string")).then(innerConditional).else(namedType("never"));
47
+ expect(stringify(outerConditional)).toMatchInlineSnapshot(`"T extends string ? A extends B ? C : D : never"`);
48
+ });
49
+ test("with generic types", () => {
50
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("U")).then(namedType("T")).else(namedType("never"));
51
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends U ? T : never"`);
52
+ });
53
+ test("complex real-world example", () => {
54
+ const conditional = conditionalType().check(namedType("T")).extends(array(namedType("any"))).then(namedType("T[0]")).else(namedType("T"));
55
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends any[] ? T[0] : T"`);
56
+ });
57
+ test("with literal types", () => {
58
+ const conditional = conditionalType().check(namedType("T")).extends(namedType('"foo"')).then(namedType("true")).else(namedType("false"));
59
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends "foo" ? true : false"`);
60
+ });
61
+ test("with intersection types", () => {
62
+ const intersection = intersectionType(A).addType(B);
63
+ const conditional = conditionalType().check(namedType("T")).extends(intersection).then(namedType("HasBoth")).else(namedType("NotBoth"));
64
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends A & B ? HasBoth : NotBoth"`);
65
+ });
66
+ test("with tuple types", () => {
67
+ const tupleType = namedType("[string, number]");
68
+ const conditional = conditionalType().check(namedType("T")).extends(tupleType).then(namedType("IsTuple")).else(namedType("NotTuple"));
69
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends [string, number] ? IsTuple : NotTuple"`);
70
+ });
71
+ test("with keyof type", () => {
72
+ const conditional = conditionalType().check(namedType("K")).extends(namedType("keyof T")).then(namedType("K")).else(namedType("never"));
73
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"K extends keyof T ? K : never"`);
74
+ });
75
+ test("with never type", () => {
76
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("never")).then(namedType("NeverReached")).else(namedType("NotNever"));
77
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends never ? NeverReached : NotNever"`);
78
+ });
79
+ test("with unknown type", () => {
80
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("unknown")).then(namedType("AlwaysTrue")).else(namedType("NeverReached"));
81
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends unknown ? AlwaysTrue : NeverReached"`);
82
+ });
83
+ test("with any type", () => {
84
+ const conditional = conditionalType().check(namedType("any")).extends(namedType("T")).then(namedType("AnyExtendsT")).else(namedType("NotExtends"));
85
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"any extends T ? AnyExtendsT : NotExtends"`);
86
+ });
87
+ test("deeply nested conditional types", () => {
88
+ const deeplyNested = conditionalType().check(namedType("T")).extends(namedType("string")).then(
89
+ conditionalType().check(namedType("U")).extends(namedType("number")).then(
90
+ conditionalType().check(namedType("V")).extends(namedType("boolean")).then(namedType("AllMatch")).else(namedType("VNotBoolean"))
91
+ ).else(namedType("UNotNumber"))
92
+ ).else(namedType("TNotString"));
93
+ expect(stringify(deeplyNested)).toMatchInlineSnapshot(
94
+ `"T extends string ? U extends number ? V extends boolean ? AllMatch : VNotBoolean : UNotNumber : TNotString"`
95
+ );
96
+ });
97
+ test("with template literal types", () => {
98
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("`prefix_${string}`")).then(namedType("HasPrefix")).else(namedType("NoPrefix"));
99
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends \`prefix_\${string}\` ? HasPrefix : NoPrefix"`);
100
+ });
101
+ test("with infer keyword", () => {
102
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("Promise<infer U>")).then(namedType("U")).else(namedType("never"));
103
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T extends Promise<infer U> ? U : never"`);
104
+ });
105
+ test("conditional type in union", () => {
106
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("string")).then(namedType("A")).else(namedType("B"));
107
+ const union = unionType(conditional).addVariant(namedType("C"));
108
+ expect(stringify(union)).toMatchInlineSnapshot(`"(T extends string ? A : B) | C"`);
109
+ });
110
+ test("with mapped type notation", () => {
111
+ const conditional = conditionalType().check(namedType("T[K]")).extends(namedType("Function")).then(namedType("K")).else(namedType("never"));
112
+ expect(stringify(conditional)).toMatchInlineSnapshot(`"T[K] extends Function ? K : never"`);
113
+ });
@@ -6,6 +6,7 @@ export declare class FunctionType extends TypeBuilder {
6
6
  needsParenthesisWhenIndexed: boolean;
7
7
  needsParenthesisInKeyof: boolean;
8
8
  needsParenthesisInUnion: boolean;
9
+ needsParenthesisInIntersection: boolean;
9
10
  private returnType;
10
11
  private parameters;
11
12
  private genericParameters;
@@ -28,6 +28,7 @@ class FunctionType extends import_TypeBuilder.TypeBuilder {
28
28
  needsParenthesisWhenIndexed = true;
29
29
  needsParenthesisInKeyof = true;
30
30
  needsParenthesisInUnion = true;
31
+ needsParenthesisInIntersection = true;
31
32
  returnType = import_PrimitiveType.voidType;
32
33
  parameters = [];
33
34
  genericParameters = [];
@@ -4,6 +4,7 @@ class FunctionType extends TypeBuilder {
4
4
  needsParenthesisWhenIndexed = true;
5
5
  needsParenthesisInKeyof = true;
6
6
  needsParenthesisInUnion = true;
7
+ needsParenthesisInIntersection = true;
7
8
  returnType = voidType;
8
9
  parameters = [];
9
10
  genericParameters = [];
@@ -3,7 +3,7 @@ import { NamedType } from './NamedType';
3
3
  import { TypeBuilder } from './TypeBuilder';
4
4
  import { Writer } from './Writer';
5
5
  export declare class GenericParameter implements BasicBuilder {
6
- private name;
6
+ readonly name: string;
7
7
  private extendedType?;
8
8
  private defaultType?;
9
9
  constructor(name: string);
@@ -0,0 +1,13 @@
1
+ import { TypeBuilder } from './TypeBuilder';
2
+ import { Writer } from './Writer';
3
+ export declare class IntersectionType<MemberType extends TypeBuilder = TypeBuilder> extends TypeBuilder {
4
+ needsParenthesisWhenIndexed: boolean;
5
+ needsParenthesisInKeyof: boolean;
6
+ readonly members: MemberType[];
7
+ constructor(firstType: MemberType);
8
+ addType(type: MemberType): this;
9
+ addTypes(types: MemberType[]): this;
10
+ write(writer: Writer): void;
11
+ mapTypes<NewMemberType extends TypeBuilder>(callback: (type: MemberType) => NewMemberType): IntersectionType<NewMemberType>;
12
+ }
13
+ export declare function intersectionType<MemberType extends TypeBuilder = TypeBuilder>(types: MemberType[] | MemberType): IntersectionType<MemberType>;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var IntersectionType_exports = {};
20
+ __export(IntersectionType_exports, {
21
+ IntersectionType: () => IntersectionType,
22
+ intersectionType: () => intersectionType
23
+ });
24
+ module.exports = __toCommonJS(IntersectionType_exports);
25
+ var import_TypeBuilder = require("./TypeBuilder");
26
+ class IntersectionType extends import_TypeBuilder.TypeBuilder {
27
+ needsParenthesisWhenIndexed = true;
28
+ needsParenthesisInKeyof = true;
29
+ members;
30
+ constructor(firstType) {
31
+ super();
32
+ this.members = [firstType];
33
+ }
34
+ addType(type) {
35
+ this.members.push(type);
36
+ return this;
37
+ }
38
+ addTypes(types) {
39
+ for (const type of types) {
40
+ this.addType(type);
41
+ }
42
+ return this;
43
+ }
44
+ write(writer) {
45
+ writer.writeJoined(" & ", this.members, (member, writer2) => {
46
+ if (member.needsParenthesisInIntersection) {
47
+ writer2.write("(").write(member).write(")");
48
+ } else {
49
+ writer2.write(member);
50
+ }
51
+ });
52
+ }
53
+ mapTypes(callback) {
54
+ return intersectionType(this.members.map((m) => callback(m)));
55
+ }
56
+ }
57
+ function intersectionType(types) {
58
+ if (Array.isArray(types)) {
59
+ if (types.length === 0) {
60
+ throw new TypeError("Intersection types array can not be empty");
61
+ }
62
+ const intersection = new IntersectionType(types[0]);
63
+ for (let i = 1; i < types.length; i++) {
64
+ intersection.addType(types[i]);
65
+ }
66
+ return intersection;
67
+ }
68
+ return new IntersectionType(types);
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ IntersectionType,
73
+ intersectionType
74
+ });
@@ -0,0 +1,49 @@
1
+ import { TypeBuilder } from "./TypeBuilder";
2
+ class IntersectionType extends TypeBuilder {
3
+ needsParenthesisWhenIndexed = true;
4
+ needsParenthesisInKeyof = true;
5
+ members;
6
+ constructor(firstType) {
7
+ super();
8
+ this.members = [firstType];
9
+ }
10
+ addType(type) {
11
+ this.members.push(type);
12
+ return this;
13
+ }
14
+ addTypes(types) {
15
+ for (const type of types) {
16
+ this.addType(type);
17
+ }
18
+ return this;
19
+ }
20
+ write(writer) {
21
+ writer.writeJoined(" & ", this.members, (member, writer2) => {
22
+ if (member.needsParenthesisInIntersection) {
23
+ writer2.write("(").write(member).write(")");
24
+ } else {
25
+ writer2.write(member);
26
+ }
27
+ });
28
+ }
29
+ mapTypes(callback) {
30
+ return intersectionType(this.members.map((m) => callback(m)));
31
+ }
32
+ }
33
+ function intersectionType(types) {
34
+ if (Array.isArray(types)) {
35
+ if (types.length === 0) {
36
+ throw new TypeError("Intersection types array can not be empty");
37
+ }
38
+ const intersection = new IntersectionType(types[0]);
39
+ for (let i = 1; i < types.length; i++) {
40
+ intersection.addType(types[i]);
41
+ }
42
+ return intersection;
43
+ }
44
+ return new IntersectionType(types);
45
+ }
46
+ export {
47
+ IntersectionType,
48
+ intersectionType
49
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_ArrayType = require("./ArrayType");
4
+ var import_ConditionalType = require("./ConditionalType");
5
+ var import_FunctionType = require("./FunctionType");
6
+ var import_IntersectionType = require("./IntersectionType");
7
+ var import_NamedType = require("./NamedType");
8
+ var import_ObjectType = require("./ObjectType");
9
+ var import_Parameter = require("./Parameter");
10
+ var import_Property = require("./Property");
11
+ var import_stringify = require("./stringify");
12
+ var import_UnionType = require("./UnionType");
13
+ const A = (0, import_NamedType.namedType)("A");
14
+ const B = (0, import_NamedType.namedType)("B");
15
+ const C = (0, import_NamedType.namedType)("C");
16
+ (0, import_vitest.test)("one type", () => {
17
+ (0, import_vitest.expect)((0, import_stringify.stringify)((0, import_IntersectionType.intersectionType)(A))).toMatchInlineSnapshot(`"A"`);
18
+ });
19
+ (0, import_vitest.test)("multiple types", () => {
20
+ (0, import_vitest.expect)((0, import_stringify.stringify)((0, import_IntersectionType.intersectionType)(A).addType(B))).toMatchInlineSnapshot(`"A & B"`);
21
+ });
22
+ (0, import_vitest.test)("three types", () => {
23
+ (0, import_vitest.expect)((0, import_stringify.stringify)((0, import_IntersectionType.intersectionType)(A).addType(B).addType(C))).toMatchInlineSnapshot(`"A & B & C"`);
24
+ });
25
+ (0, import_vitest.test)("from array", () => {
26
+ (0, import_vitest.expect)((0, import_stringify.stringify)((0, import_IntersectionType.intersectionType)([A, B, C]))).toMatchInlineSnapshot(`"A & B & C"`);
27
+ });
28
+ (0, import_vitest.test)("with function type", () => {
29
+ const funcType = (0, import_FunctionType.functionType)().addParameter((0, import_Parameter.parameter)("x", (0, import_NamedType.namedType)("string"))).setReturnType((0, import_NamedType.namedType)("void"));
30
+ (0, import_vitest.expect)((0, import_stringify.stringify)((0, import_IntersectionType.intersectionType)([A, B, funcType]))).toMatchInlineSnapshot(`"A & B & ((x: string) => void)"`);
31
+ });
32
+ (0, import_vitest.test)("with object types", () => {
33
+ const obj1 = (0, import_ObjectType.objectType)().add((0, import_Property.property)("name", (0, import_NamedType.namedType)("string")));
34
+ const obj2 = (0, import_ObjectType.objectType)().add((0, import_Property.property)("age", (0, import_NamedType.namedType)("number")));
35
+ const intersection = (0, import_IntersectionType.intersectionType)(obj1).addType(obj2);
36
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`
37
+ "{
38
+ name: string
39
+ } & {
40
+ age: number
41
+ }"
42
+ `);
43
+ });
44
+ (0, import_vitest.test)("with array types", () => {
45
+ const intersection = (0, import_IntersectionType.intersectionType)((0, import_ArrayType.array)(A)).addType((0, import_ArrayType.array)(B));
46
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"A[] & B[]"`);
47
+ });
48
+ (0, import_vitest.test)("with union types", () => {
49
+ const union1 = (0, import_UnionType.unionType)(A).addVariant(B);
50
+ const union2 = (0, import_UnionType.unionType)(C).addVariant((0, import_NamedType.namedType)("D"));
51
+ const intersection = (0, import_IntersectionType.intersectionType)(union1).addType(union2);
52
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"(A | B) & (C | D)"`);
53
+ });
54
+ (0, import_vitest.test)("fails with empty array", () => {
55
+ (0, import_vitest.expect)(() => (0, import_IntersectionType.intersectionType)([])).toThrowErrorMatchingInlineSnapshot(
56
+ `[TypeError: Intersection types array can not be empty]`
57
+ );
58
+ });
59
+ (0, import_vitest.test)("mapTypes", () => {
60
+ const intersection = (0, import_IntersectionType.intersectionType)([A, B, C]).mapTypes(import_ArrayType.array);
61
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"A[] & B[] & C[]"`);
62
+ });
63
+ (0, import_vitest.test)("with generic types", () => {
64
+ const intersection = (0, import_IntersectionType.intersectionType)((0, import_NamedType.namedType)("T")).addType((0, import_NamedType.namedType)("U"));
65
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"T & U"`);
66
+ });
67
+ (0, import_vitest.test)("with literal types", () => {
68
+ const intersection = (0, import_IntersectionType.intersectionType)((0, import_NamedType.namedType)('"foo"')).addType((0, import_NamedType.namedType)('"bar"'));
69
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`""foo" & "bar""`);
70
+ });
71
+ (0, import_vitest.test)("nested intersection types", () => {
72
+ const inner = (0, import_IntersectionType.intersectionType)(A).addType(B);
73
+ const outer = (0, import_IntersectionType.intersectionType)(inner).addType(C);
74
+ (0, import_vitest.expect)((0, import_stringify.stringify)(outer)).toMatchInlineSnapshot(`"A & B & C"`);
75
+ });
76
+ (0, import_vitest.test)("with conditional type", () => {
77
+ const conditional = (0, import_ConditionalType.conditionalType)().check((0, import_NamedType.namedType)("T")).extends((0, import_NamedType.namedType)("string")).then(A).else(B);
78
+ const intersection = (0, import_IntersectionType.intersectionType)(conditional).addType(C);
79
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"(T extends string ? A : B) & C"`);
80
+ });
81
+ (0, import_vitest.test)("with keyof type", () => {
82
+ const intersection = (0, import_IntersectionType.intersectionType)((0, import_NamedType.namedType)("keyof T")).addType((0, import_NamedType.namedType)("string"));
83
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"keyof T & string"`);
84
+ });
85
+ (0, import_vitest.test)("complex real-world example", () => {
86
+ const baseType = (0, import_ObjectType.objectType)().add((0, import_Property.property)("id", (0, import_NamedType.namedType)("string"))).add((0, import_Property.property)("createdAt", (0, import_NamedType.namedType)("Date")));
87
+ const userFields = (0, import_ObjectType.objectType)().add((0, import_Property.property)("name", (0, import_NamedType.namedType)("string"))).add((0, import_Property.property)("email", (0, import_NamedType.namedType)("string")));
88
+ const permissions = (0, import_ObjectType.objectType)().add(
89
+ (0, import_Property.property)("role", (0, import_UnionType.unionType)((0, import_NamedType.namedType)('"admin"')).addVariant((0, import_NamedType.namedType)('"user"')))
90
+ );
91
+ const userType = (0, import_IntersectionType.intersectionType)(baseType).addType(userFields).addType(permissions);
92
+ (0, import_vitest.expect)((0, import_stringify.stringify)(userType)).toMatchInlineSnapshot(`
93
+ "{
94
+ id: string
95
+ createdAt: Date
96
+ } & {
97
+ name: string
98
+ email: string
99
+ } & {
100
+ role: "admin" | "user"
101
+ }"
102
+ `);
103
+ });
104
+ (0, import_vitest.test)("addTypes with multiple types", () => {
105
+ const intersection = (0, import_IntersectionType.intersectionType)(A).addTypes([B, C]);
106
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"A & B & C"`);
107
+ });
108
+ (0, import_vitest.test)("with never type", () => {
109
+ const intersection = (0, import_IntersectionType.intersectionType)(A).addType((0, import_NamedType.namedType)("never"));
110
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"A & never"`);
111
+ });
112
+ (0, import_vitest.test)("with unknown type", () => {
113
+ const intersection = (0, import_IntersectionType.intersectionType)(A).addType((0, import_NamedType.namedType)("unknown"));
114
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"A & unknown"`);
115
+ });
116
+ (0, import_vitest.test)("with any type", () => {
117
+ const intersection = (0, import_IntersectionType.intersectionType)((0, import_NamedType.namedType)("any")).addType(B);
118
+ (0, import_vitest.expect)((0, import_stringify.stringify)(intersection)).toMatchInlineSnapshot(`"any & B"`);
119
+ });
@@ -0,0 +1,118 @@
1
+ import { expect, test } from "vitest";
2
+ import { array } from "./ArrayType";
3
+ import { conditionalType } from "./ConditionalType";
4
+ import { functionType } from "./FunctionType";
5
+ import { intersectionType } from "./IntersectionType";
6
+ import { namedType } from "./NamedType";
7
+ import { objectType } from "./ObjectType";
8
+ import { parameter } from "./Parameter";
9
+ import { property } from "./Property";
10
+ import { stringify } from "./stringify";
11
+ import { unionType } from "./UnionType";
12
+ const A = namedType("A");
13
+ const B = namedType("B");
14
+ const C = namedType("C");
15
+ test("one type", () => {
16
+ expect(stringify(intersectionType(A))).toMatchInlineSnapshot(`"A"`);
17
+ });
18
+ test("multiple types", () => {
19
+ expect(stringify(intersectionType(A).addType(B))).toMatchInlineSnapshot(`"A & B"`);
20
+ });
21
+ test("three types", () => {
22
+ expect(stringify(intersectionType(A).addType(B).addType(C))).toMatchInlineSnapshot(`"A & B & C"`);
23
+ });
24
+ test("from array", () => {
25
+ expect(stringify(intersectionType([A, B, C]))).toMatchInlineSnapshot(`"A & B & C"`);
26
+ });
27
+ test("with function type", () => {
28
+ const funcType = functionType().addParameter(parameter("x", namedType("string"))).setReturnType(namedType("void"));
29
+ expect(stringify(intersectionType([A, B, funcType]))).toMatchInlineSnapshot(`"A & B & ((x: string) => void)"`);
30
+ });
31
+ test("with object types", () => {
32
+ const obj1 = objectType().add(property("name", namedType("string")));
33
+ const obj2 = objectType().add(property("age", namedType("number")));
34
+ const intersection = intersectionType(obj1).addType(obj2);
35
+ expect(stringify(intersection)).toMatchInlineSnapshot(`
36
+ "{
37
+ name: string
38
+ } & {
39
+ age: number
40
+ }"
41
+ `);
42
+ });
43
+ test("with array types", () => {
44
+ const intersection = intersectionType(array(A)).addType(array(B));
45
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"A[] & B[]"`);
46
+ });
47
+ test("with union types", () => {
48
+ const union1 = unionType(A).addVariant(B);
49
+ const union2 = unionType(C).addVariant(namedType("D"));
50
+ const intersection = intersectionType(union1).addType(union2);
51
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"(A | B) & (C | D)"`);
52
+ });
53
+ test("fails with empty array", () => {
54
+ expect(() => intersectionType([])).toThrowErrorMatchingInlineSnapshot(
55
+ `[TypeError: Intersection types array can not be empty]`
56
+ );
57
+ });
58
+ test("mapTypes", () => {
59
+ const intersection = intersectionType([A, B, C]).mapTypes(array);
60
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"A[] & B[] & C[]"`);
61
+ });
62
+ test("with generic types", () => {
63
+ const intersection = intersectionType(namedType("T")).addType(namedType("U"));
64
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"T & U"`);
65
+ });
66
+ test("with literal types", () => {
67
+ const intersection = intersectionType(namedType('"foo"')).addType(namedType('"bar"'));
68
+ expect(stringify(intersection)).toMatchInlineSnapshot(`""foo" & "bar""`);
69
+ });
70
+ test("nested intersection types", () => {
71
+ const inner = intersectionType(A).addType(B);
72
+ const outer = intersectionType(inner).addType(C);
73
+ expect(stringify(outer)).toMatchInlineSnapshot(`"A & B & C"`);
74
+ });
75
+ test("with conditional type", () => {
76
+ const conditional = conditionalType().check(namedType("T")).extends(namedType("string")).then(A).else(B);
77
+ const intersection = intersectionType(conditional).addType(C);
78
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"(T extends string ? A : B) & C"`);
79
+ });
80
+ test("with keyof type", () => {
81
+ const intersection = intersectionType(namedType("keyof T")).addType(namedType("string"));
82
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"keyof T & string"`);
83
+ });
84
+ test("complex real-world example", () => {
85
+ const baseType = objectType().add(property("id", namedType("string"))).add(property("createdAt", namedType("Date")));
86
+ const userFields = objectType().add(property("name", namedType("string"))).add(property("email", namedType("string")));
87
+ const permissions = objectType().add(
88
+ property("role", unionType(namedType('"admin"')).addVariant(namedType('"user"')))
89
+ );
90
+ const userType = intersectionType(baseType).addType(userFields).addType(permissions);
91
+ expect(stringify(userType)).toMatchInlineSnapshot(`
92
+ "{
93
+ id: string
94
+ createdAt: Date
95
+ } & {
96
+ name: string
97
+ email: string
98
+ } & {
99
+ role: "admin" | "user"
100
+ }"
101
+ `);
102
+ });
103
+ test("addTypes with multiple types", () => {
104
+ const intersection = intersectionType(A).addTypes([B, C]);
105
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"A & B & C"`);
106
+ });
107
+ test("with never type", () => {
108
+ const intersection = intersectionType(A).addType(namedType("never"));
109
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"A & never"`);
110
+ });
111
+ test("with unknown type", () => {
112
+ const intersection = intersectionType(A).addType(namedType("unknown"));
113
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"A & unknown"`);
114
+ });
115
+ test("with any type", () => {
116
+ const intersection = intersectionType(namedType("any")).addType(B);
117
+ expect(stringify(intersection)).toMatchInlineSnapshot(`"any & B"`);
118
+ });
@@ -5,6 +5,7 @@ export declare abstract class TypeBuilder implements BasicBuilder {
5
5
  needsParenthesisWhenIndexed: boolean;
6
6
  needsParenthesisInKeyof: boolean;
7
7
  needsParenthesisInUnion: boolean;
8
+ needsParenthesisInIntersection: boolean;
8
9
  abstract write(writer: Writer): void;
9
10
  subKey(key: string): KeyType;
10
11
  writeIndexed(writer: Writer): void;
@@ -27,6 +27,7 @@ class TypeBuilder {
27
27
  needsParenthesisWhenIndexed = false;
28
28
  needsParenthesisInKeyof = false;
29
29
  needsParenthesisInUnion = false;
30
+ needsParenthesisInIntersection = false;
30
31
  subKey(key) {
31
32
  const { KeyType } = require("./KeyType");
32
33
  return new KeyType(this, key);
@@ -4,6 +4,7 @@ class TypeBuilder {
4
4
  needsParenthesisWhenIndexed = false;
5
5
  needsParenthesisInKeyof = false;
6
6
  needsParenthesisInUnion = false;
7
+ needsParenthesisInIntersection = false;
7
8
  subKey(key) {
8
9
  const { KeyType } = require("./KeyType");
9
10
  return new KeyType(this, key);
@@ -3,6 +3,7 @@ import { Writer } from './Writer';
3
3
  export declare class UnionType<VariantType extends TypeBuilder = TypeBuilder> extends TypeBuilder {
4
4
  needsParenthesisWhenIndexed: boolean;
5
5
  needsParenthesisInKeyof: boolean;
6
+ needsParenthesisInIntersection: boolean;
6
7
  readonly variants: VariantType[];
7
8
  constructor(firstType: VariantType);
8
9
  addVariant(variant: VariantType): this;
package/dist/UnionType.js CHANGED
@@ -26,6 +26,7 @@ var import_TypeBuilder = require("./TypeBuilder");
26
26
  class UnionType extends import_TypeBuilder.TypeBuilder {
27
27
  needsParenthesisWhenIndexed = true;
28
28
  needsParenthesisInKeyof = true;
29
+ needsParenthesisInIntersection = true;
29
30
  variants;
30
31
  constructor(firstType) {
31
32
  super();
@@ -2,6 +2,7 @@ import { TypeBuilder } from "./TypeBuilder";
2
2
  class UnionType extends TypeBuilder {
3
3
  needsParenthesisWhenIndexed = true;
4
4
  needsParenthesisInKeyof = true;
5
+ needsParenthesisInIntersection = true;
5
6
  variants;
6
7
  constructor(firstType) {
7
8
  super();
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from './ArraySpread';
3
3
  export * from './ArrayType';
4
4
  export * from './BasicBuilder';
5
5
  export * from './Class';
6
+ export * from './ConditionalType';
6
7
  export * from './ConstDeclaration';
7
8
  export * from './DocComment';
8
9
  export * from './Export';
@@ -14,6 +15,7 @@ export * from './GenericParameter';
14
15
  export * from './helpers';
15
16
  export * from './Import';
16
17
  export * from './Interface';
18
+ export * from './IntersectionType';
17
19
  export * from './KeyofType';
18
20
  export * from './KeyType';
19
21
  export * from './Method';
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ __reExport(index_exports, require("./ArraySpread"), module.exports);
20
20
  __reExport(index_exports, require("./ArrayType"), module.exports);
21
21
  __reExport(index_exports, require("./BasicBuilder"), module.exports);
22
22
  __reExport(index_exports, require("./Class"), module.exports);
23
+ __reExport(index_exports, require("./ConditionalType"), module.exports);
23
24
  __reExport(index_exports, require("./ConstDeclaration"), module.exports);
24
25
  __reExport(index_exports, require("./DocComment"), module.exports);
25
26
  __reExport(index_exports, require("./Export"), module.exports);
@@ -31,6 +32,7 @@ __reExport(index_exports, require("./GenericParameter"), module.exports);
31
32
  __reExport(index_exports, require("./helpers"), module.exports);
32
33
  __reExport(index_exports, require("./Import"), module.exports);
33
34
  __reExport(index_exports, require("./Interface"), module.exports);
35
+ __reExport(index_exports, require("./IntersectionType"), module.exports);
34
36
  __reExport(index_exports, require("./KeyofType"), module.exports);
35
37
  __reExport(index_exports, require("./KeyType"), module.exports);
36
38
  __reExport(index_exports, require("./Method"), module.exports);
@@ -57,6 +59,7 @@ __reExport(index_exports, require("./Writer"), module.exports);
57
59
  ...require("./ArrayType"),
58
60
  ...require("./BasicBuilder"),
59
61
  ...require("./Class"),
62
+ ...require("./ConditionalType"),
60
63
  ...require("./ConstDeclaration"),
61
64
  ...require("./DocComment"),
62
65
  ...require("./Export"),
@@ -68,6 +71,7 @@ __reExport(index_exports, require("./Writer"), module.exports);
68
71
  ...require("./helpers"),
69
72
  ...require("./Import"),
70
73
  ...require("./Interface"),
74
+ ...require("./IntersectionType"),
71
75
  ...require("./KeyofType"),
72
76
  ...require("./KeyType"),
73
77
  ...require("./Method"),
package/dist/index.mjs CHANGED
@@ -3,6 +3,7 @@ export * from "./ArraySpread";
3
3
  export * from "./ArrayType";
4
4
  export * from "./BasicBuilder";
5
5
  export * from "./Class";
6
+ export * from "./ConditionalType";
6
7
  export * from "./ConstDeclaration";
7
8
  export * from "./DocComment";
8
9
  export * from "./Export";
@@ -14,6 +15,7 @@ export * from "./GenericParameter";
14
15
  export * from "./helpers";
15
16
  export * from "./Import";
16
17
  export * from "./Interface";
18
+ export * from "./IntersectionType";
17
19
  export * from "./KeyofType";
18
20
  export * from "./KeyType";
19
21
  export * from "./Method";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/ts-builders",
3
- "version": "6.13.0-dev.2",
3
+ "version": "6.13.0-dev.20",
4
4
  "description": "This package is intended for Prisma's internal use",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "license": "Apache-2.0",
26
26
  "dependencies": {
27
- "@prisma/internals": "6.13.0-dev.2"
27
+ "@prisma/internals": "6.13.0-dev.20"
28
28
  },
29
29
  "devDependencies": {
30
30
  "vitest": "3.0.9"