Skip to content

Commit e039eb8

Browse files
committed
feat: Support for query types
1 parent 64a2a4f commit e039eb8

File tree

13 files changed

+198
-28
lines changed

13 files changed

+198
-28
lines changed

src/lib/converter/plugins/TypePlugin.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Reflection, ReflectionKind, Decorator, DeclarationReflection, DeclarationHierarchy } from '../../models/reflections/index';
2-
import { Type, ReferenceType, TupleType, UnionType, IntersectionType, ArrayType, TypeOperatorType } from '../../models/types/index';
2+
import { Type, ReferenceType, TupleType, UnionType, IntersectionType, ArrayType, TypeOperatorType, QueryType } from '../../models/types/index';
33
import { Component, ConverterComponent } from '../components';
44
import { Converter } from '../converter';
55
import { Context } from '../context';
@@ -108,6 +108,8 @@ export class TypePlugin extends ConverterComponent {
108108
resolveType(reflection, type.elementType);
109109
} else if (type instanceof TypeOperatorType) {
110110
resolveType(reflection, type.target);
111+
} else if (type instanceof QueryType) {
112+
resolveType(reflection, type.queryType);
111113
}
112114
}
113115
}

src/lib/converter/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { InferredConverter } from './inferred';
88
export { IndexedAccessConverter } from './indexed-access';
99
export { IntrinsicConverter } from './intrinsic';
1010
export { PredicateConverter } from './predicate';
11+
export { QueryConverter } from './query';
1112
export { StringLiteralConverter } from './string-literal';
1213
export { ReferenceConverter } from './reference';
1314
export { ThisConverter } from './this';

src/lib/converter/types/query.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as ts from 'typescript';
2+
3+
import { Type, QueryType } from '../../models/types/index';
4+
import { Component, ConverterTypeComponent, TypeNodeConverter } from '../components';
5+
import { Context } from '../context';
6+
import { createReferenceType } from '../factories';
7+
8+
@Component({name: 'type:query'})
9+
export class QueryConverter extends ConverterTypeComponent implements TypeNodeConverter<ts.Type, ts.TypeQueryNode> {
10+
supportsNode(_context: Context, node: ts.Node): boolean {
11+
return ts.isTypeQueryNode(node);
12+
}
13+
14+
convertNode(context: Context, node: ts.TypeQueryNode): Type | undefined {
15+
const querySymbol = context.getSymbolAtLocation(node.exprName);
16+
if (querySymbol) {
17+
const reference = createReferenceType(context, querySymbol);
18+
if (reference) {
19+
return new QueryType(reference);
20+
}
21+
}
22+
}
23+
24+
}

src/lib/models/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { IndexedAccessType } from './indexed-access';
55
export { InferredType } from './inferred';
66
export { IntersectionType } from './intersection';
77
export { IntrinsicType } from './intrinsic';
8+
export { QueryType } from './query';
89
export { PredicateType } from './predicate';
910
export { ReferenceType } from './reference';
1011
export { ReflectionType } from './reflection';

src/lib/models/types/query.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Type } from './abstract';
2+
import { ReferenceType } from './reference';
3+
4+
/**
5+
* Represents a type that is constructed by querying the type of a reflection.
6+
* ```ts
7+
* const x = 1
8+
* type Z = typeof x // query on reflection for x
9+
* ```
10+
*/
11+
export class QueryType extends Type {
12+
readonly queryType: ReferenceType;
13+
14+
readonly type = 'query';
15+
16+
constructor(reference: ReferenceType) {
17+
super();
18+
this.queryType = reference;
19+
}
20+
21+
clone(): Type {
22+
return new QueryType(this.queryType);
23+
}
24+
25+
equals(other: Type) {
26+
return other instanceof QueryType && this.queryType.equals(other.queryType);
27+
}
28+
29+
toString() {
30+
return `typeof ${this.queryType.toString()}`;
31+
}
32+
}

src/lib/serialization/schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ export interface IntersectionType extends Type, S<M.IntersectionType, 'type' | '
198198
export interface IntrinsicType extends Type, S<M.IntrinsicType, 'type' | 'name'> {
199199
}
200200

201+
export interface QueryType extends Type, S<M.QueryType, 'type' | 'queryType'> {
202+
}
203+
201204
export interface PredicateType extends Type, S<M.PredicateType, 'type' | 'name' | 'asserts' | 'targetType'> {
202205
}
203206

src/lib/serialization/serializer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ const serializerComponents: (new (owner: Serializer) => SerializerComponent<any>
114114
S.InferredTypeSerializer,
115115
S.IntersectionTypeSerializer,
116116
S.IntrinsicTypeSerializer,
117+
S.QueryTypeSerializer,
117118
S.PredicateTypeSerializer,
118119
S.ReferenceTypeSerializer,
119120
S.ReferenceTypeSerializer,

src/lib/serialization/serializers/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './inferred';
66
export * from './intersection';
77
export * from './intrinsic';
88
export * from './predicate';
9+
export * from './query';
910
export * from './reference';
1011
export * from './reflection';
1112
export * from './string-literal';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { QueryType } from '../../../models';
2+
import { TypeSerializerComponent } from '../../components';
3+
import { QueryType as JSONQueryType } from '../../schema';
4+
5+
export class QueryTypeSerializer extends TypeSerializerComponent<QueryType> {
6+
supports(t: unknown) {
7+
return t instanceof QueryType;
8+
}
9+
10+
toObject(type: QueryType, obj: Pick<JSONQueryType, 'type'>): JSONQueryType {
11+
return {
12+
...obj,
13+
queryType: this.owner.toObject(type.queryType)
14+
};
15+
}
16+
}

src/test/converter/mixin/specs.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,8 +1318,12 @@
13181318
"id": 51,
13191319
"typeArguments": [
13201320
{
1321-
"type": "reference",
1322-
"name": "Mixin3"
1321+
"type": "query",
1322+
"queryType": {
1323+
"type": "reference",
1324+
"id": 61,
1325+
"name": "Mixin3"
1326+
}
13231327
}
13241328
],
13251329
"name": "Mixin"

0 commit comments

Comments
 (0)