Skip to content

Commit cdd6370

Browse files
kittendeathemperorHaiNNT
authored
fix: Add tail recursion where it's possible but missing (#51)
Co-authored-by: deathemperor <[email protected]> Co-authored-by: HaiNNT <[email protected]>
1 parent 4dc30de commit cdd6370

File tree

3 files changed

+90
-67
lines changed

3 files changed

+90
-67
lines changed

.changeset/short-teachers-begin.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'gql.tada': patch
3+
---
4+
5+
Improve performance of several smaller types (Thank you, [@deathemperor](https://github.com/deathemperor) & [@HaiNNT](https://github.com/HaiNNT))

src/selection.ts

+46-38
Original file line numberDiff line numberDiff line change
@@ -134,45 +134,53 @@ type _getPossibleTypeSelectionRec<
134134
Type extends ObjectLikeType,
135135
Introspection extends IntrospectionLikeType,
136136
Fragments extends { [name: string]: any },
137+
SelectionAcc = {},
137138
> = Selections extends [infer Node, ...infer Rest]
138-
? (Node extends { kind: Kind.FRAGMENT_SPREAD | Kind.INLINE_FRAGMENT }
139-
? getSpreadSubtype<Node, Type, Introspection, Fragments> extends infer Subtype extends
140-
ObjectLikeType
141-
? PossibleType extends getTypenameOfType<Subtype>
142-
?
143-
| (isOptional<Node> extends true ? {} : never)
144-
| getFragmentSelection<Node, Subtype, Introspection, Fragments>
145-
: {}
146-
: Node extends { kind: Kind.FRAGMENT_SPREAD; name: any }
147-
? makeUndefinedFragmentRef<Node['name']['value']>
148-
: {}
149-
: Node extends { kind: Kind.FIELD; name: any; selectionSet: any }
150-
? isOptional<Node> extends true
151-
? {
152-
[Prop in getFieldAlias<Node>]?: Node['name']['value'] extends '__typename'
153-
? PossibleType
154-
: unwrapType<
155-
Type['fields'][Node['name']['value']]['type'],
156-
Node['selectionSet'],
157-
Introspection,
158-
Fragments,
159-
getTypeDirective<Node>
160-
>;
161-
}
162-
: {
163-
[Prop in getFieldAlias<Node>]: Node['name']['value'] extends '__typename'
164-
? PossibleType
165-
: unwrapType<
166-
Type['fields'][Node['name']['value']]['type'],
167-
Node['selectionSet'],
168-
Introspection,
169-
Fragments,
170-
getTypeDirective<Node>
171-
>;
172-
}
173-
: {}) &
174-
_getPossibleTypeSelectionRec<Rest, PossibleType, Type, Introspection, Fragments>
175-
: {};
139+
? _getPossibleTypeSelectionRec<
140+
Rest,
141+
PossibleType,
142+
Type,
143+
Introspection,
144+
Fragments,
145+
(Node extends { kind: Kind.FRAGMENT_SPREAD | Kind.INLINE_FRAGMENT }
146+
? getSpreadSubtype<Node, Type, Introspection, Fragments> extends infer Subtype extends
147+
ObjectLikeType
148+
? PossibleType extends getTypenameOfType<Subtype>
149+
?
150+
| (isOptional<Node> extends true ? {} : never)
151+
| getFragmentSelection<Node, Subtype, Introspection, Fragments>
152+
: {}
153+
: Node extends { kind: Kind.FRAGMENT_SPREAD; name: any }
154+
? makeUndefinedFragmentRef<Node['name']['value']>
155+
: {}
156+
: Node extends { kind: Kind.FIELD; name: any; selectionSet: any }
157+
? isOptional<Node> extends true
158+
? {
159+
[Prop in getFieldAlias<Node>]?: Node['name']['value'] extends '__typename'
160+
? PossibleType
161+
: unwrapType<
162+
Type['fields'][Node['name']['value']]['type'],
163+
Node['selectionSet'],
164+
Introspection,
165+
Fragments,
166+
getTypeDirective<Node>
167+
>;
168+
}
169+
: {
170+
[Prop in getFieldAlias<Node>]: Node['name']['value'] extends '__typename'
171+
? PossibleType
172+
: unwrapType<
173+
Type['fields'][Node['name']['value']]['type'],
174+
Node['selectionSet'],
175+
Introspection,
176+
Fragments,
177+
getTypeDirective<Node>
178+
>;
179+
}
180+
: {}) &
181+
SelectionAcc
182+
>
183+
: SelectionAcc;
176184

177185
type getOperationSelectionType<
178186
Definition,

src/variables.ts

+39-29
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ import type { obj } from './utils';
66
type getInputObjectTypeRec<
77
InputFields,
88
Introspection extends IntrospectionLikeType,
9+
InputObject = {},
910
> = InputFields extends [infer InputField, ...infer Rest]
10-
? (InputField extends { name: any; type: any }
11-
? InputField['type'] extends { kind: 'NON_NULL' }
12-
? { [Name in InputField['name']]: unwrapType<InputField['type'], Introspection> }
13-
: { [Name in InputField['name']]?: unwrapType<InputField['type'], Introspection> }
14-
: {}) &
15-
getInputObjectTypeRec<Rest, Introspection>
16-
: {};
11+
? getInputObjectTypeRec<
12+
Rest,
13+
Introspection,
14+
(InputField extends { name: any; type: any }
15+
? InputField['type'] extends { kind: 'NON_NULL' }
16+
? { [Name in InputField['name']]: unwrapType<InputField['type'], Introspection> }
17+
: { [Name in InputField['name']]?: unwrapType<InputField['type'], Introspection> }
18+
: {}) &
19+
InputObject
20+
>
21+
: InputObject;
1722

1823
type getScalarType<
1924
TypeName,
@@ -62,27 +67,32 @@ type unwrapTypeRef<Type, Introspection extends IntrospectionLikeType> = Type ext
6267
? _unwrapTypeRefRec<Type['type'], Introspection>
6368
: null | _unwrapTypeRefRec<Type, Introspection>;
6469

65-
type getVariablesRec<Variables, Introspection extends IntrospectionLikeType> = Variables extends [
66-
infer Variable,
67-
...infer Rest,
68-
]
69-
? (Variable extends { kind: Kind.VARIABLE_DEFINITION; variable: any; type: any }
70-
? Variable extends { defaultValue: undefined; type: { kind: Kind.NON_NULL_TYPE } }
71-
? {
72-
[Name in Variable['variable']['name']['value']]: unwrapTypeRef<
73-
Variable['type'],
74-
Introspection
75-
>;
76-
}
77-
: {
78-
[Name in Variable['variable']['name']['value']]?: unwrapTypeRef<
79-
Variable['type'],
80-
Introspection
81-
>;
82-
}
83-
: {}) &
84-
getVariablesRec<Rest, Introspection>
85-
: {};
70+
type _getVariablesRec<
71+
Variables,
72+
Introspection extends IntrospectionLikeType,
73+
VariablesObject = {},
74+
> = Variables extends [infer Variable, ...infer Rest]
75+
? _getVariablesRec<
76+
Rest,
77+
Introspection,
78+
(Variable extends { kind: Kind.VARIABLE_DEFINITION; variable: any; type: any }
79+
? Variable extends { defaultValue: undefined; type: { kind: Kind.NON_NULL_TYPE } }
80+
? {
81+
[Name in Variable['variable']['name']['value']]: unwrapTypeRef<
82+
Variable['type'],
83+
Introspection
84+
>;
85+
}
86+
: {
87+
[Name in Variable['variable']['name']['value']]?: unwrapTypeRef<
88+
Variable['type'],
89+
Introspection
90+
>;
91+
}
92+
: {}) &
93+
VariablesObject
94+
>
95+
: VariablesObject;
8696

8797
type getVariablesType<
8898
Document extends DocumentNodeLike,
@@ -91,7 +101,7 @@ type getVariablesType<
91101
kind: Kind.OPERATION_DEFINITION;
92102
variableDefinitions: any;
93103
}
94-
? obj<getVariablesRec<Document['definitions'][0]['variableDefinitions'], Introspection>>
104+
? obj<_getVariablesRec<Document['definitions'][0]['variableDefinitions'], Introspection>>
95105
: {};
96106

97107
export type { getVariablesType };

0 commit comments

Comments
 (0)