Skip to content

Commit 78d7df0

Browse files
committed
feat(type): support enum in pathResolver/resolvePath
1 parent 9af344f commit 78d7df0

File tree

3 files changed

+92
-8
lines changed

3 files changed

+92
-8
lines changed

packages/type/src/path.ts

+30
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,34 @@ function pathResolverCode(type: Type, compilerContext: CompilerContext, jitStack
1818
${pathResolverCode(type.type, compilerContext, jitStack)}
1919
}
2020
`;
21+
} else if (type.kind === ReflectionKind.tupleMember) {
22+
return `
23+
if (!path) return ${compilerContext.reserveVariable('type', type)};
24+
${pathResolverCode(type.type, compilerContext, jitStack)};
25+
`;
26+
} else if (type.kind === ReflectionKind.tuple) {
27+
const cases: string[] = [];
28+
for (let i = 0; i < type.types.length; i++) {
29+
cases.push(`
30+
case "${i}": {
31+
${pathResolverCode(type.types[i], compilerContext, jitStack)}
32+
}
33+
`);
34+
}
35+
36+
return `
37+
{
38+
const dotIndex = path.indexOf('.');
39+
const segment = dotIndex === -1 ? path : path.substr(0, dotIndex);
40+
path = dotIndex === -1 ? '' : path.substr(dotIndex + 1);
41+
switch (segment) {
42+
${cases.join('\n')}
43+
default: {
44+
return undefined;
45+
}
46+
}
47+
}
48+
`;
2149
} else if (type.kind === ReflectionKind.class && type.classType === Set) {
2250
} else if (type.kind === ReflectionKind.class && type.classType === Map) {
2351
} else if (type.kind === ReflectionKind.union) {
@@ -72,6 +100,8 @@ export function pathResolver<T>(type?: ReceiveType<T>, jitStack: JitStack = new
72100
const pathName = dotIndex === -1 ? path : path.substr(0, dotIndex);
73101
path = dotIndex === -1 ? '' : path.substr(dotIndex + 1);
74102
103+
if (!pathName) return ${compilerContext.reserveVariable('type', type)};
104+
75105
switch(pathName) {
76106
${lines.join('\n')}
77107
default: {

packages/type/tests/path.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ test('pathResolver deep array object', () => {
5050
expect(resolver('b.0.0.c')).toMatchObject({ kind: ReflectionKind.propertySignature, type: { kind: ReflectionKind.boolean } });
5151
});
5252

53+
test('pathResolver deep array object', () => {
54+
type t = { a: [string, number, [boolean, string, { b: number }]?] };
55+
56+
const resolver = pathResolver<t>();
57+
58+
expect(resolver('a')).toMatchObject({ kind: ReflectionKind.propertySignature, type: { kind: ReflectionKind.tuple } });
59+
60+
expect(resolver('a.0')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.string } });
61+
expect(resolver('a.1')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.number } });
62+
63+
expect(resolver('a.2.0')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.boolean } });
64+
expect(resolver('a.2.1')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.string } });
65+
expect(resolver('a.2.2')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.objectLiteral } });
66+
expect(resolver('a.2.2.b')).toMatchObject({ kind: ReflectionKind.propertySignature });
67+
});
68+
5369
test('pathResolver deep class', () => {
5470
interface Config {
5571
name: string;

packages/type/tests/typeguard.spec.ts

+46-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import { expect, test } from '@jest/globals';
1111
import { float, float32, int8, integer, PrimaryKey, Reference } from '../src/reflection/type.js';
1212
import { is } from '../src/typeguard.js';
13+
import { Serializer } from '../src/serializer.js';
14+
import { cast } from '../src/serializer-facade.js';
15+
import { isReferenceInstance } from '../src/reference.js';
1316

1417
test('primitive string', () => {
1518
expect(is<string>('a')).toEqual(true);
@@ -198,10 +201,10 @@ test('array any', () => {
198201
expect(is<any[]>(true)).toEqual(false);
199202
expect(is<any[]>({})).toEqual(false);
200203

201-
expect(is<any[]>({length:1})).toEqual(false);
202-
expect(is<any[]>({length:0})).toEqual(false);
203-
expect(is<any[]>({length:null})).toEqual(false);
204-
expect(is<any[]>({length:undefined})).toEqual(false);
204+
expect(is<any[]>({ length: 1 })).toEqual(false);
205+
expect(is<any[]>({ length: 0 })).toEqual(false);
206+
expect(is<any[]>({ length: null })).toEqual(false);
207+
expect(is<any[]>({ length: undefined })).toEqual(false);
205208
});
206209

207210
test('union', () => {
@@ -397,15 +400,50 @@ test('class with literal and default', () => {
397400
readConcernLevel: 'local' = 'local';
398401
}
399402

400-
expect(is<ConnectionOptions>({readConcernLevel: 'local'})).toBe(true);
401-
expect(is<ConnectionOptions>({readConcernLevel: 'local2'})).toBe(false);
403+
expect(is<ConnectionOptions>({ readConcernLevel: 'local' })).toBe(true);
404+
expect(is<ConnectionOptions>({ readConcernLevel: 'local2' })).toBe(false);
402405
});
403406

404407
test('union literal', () => {
405408
class ConnectionOptions {
406409
readConcernLevel: 'local' | 'majority' | 'linearizable' | 'available' = 'majority';
407410
}
408411

409-
expect(is<ConnectionOptions>({readConcernLevel: 'majority'})).toBe(true);
410-
expect(is<ConnectionOptions>({readConcernLevel: 'majority2'})).toBe(false);
412+
expect(is<ConnectionOptions>({ readConcernLevel: 'majority' })).toBe(true);
413+
expect(is<ConnectionOptions>({ readConcernLevel: 'majority2' })).toBe(false);
414+
});
415+
416+
test('union classes with generic', () => {
417+
class Group {
418+
id: number & PrimaryKey = 0;
419+
second: string = '';
420+
}
421+
422+
class User {
423+
id: number = 0;
424+
groups: (Group & Reference)[] = [];
425+
}
426+
427+
const serializer = new Serializer();
428+
429+
const newGroup = cast<Group>({ id: 1, second: 'a' });
430+
431+
const a = cast<User>({
432+
id: 1,
433+
groups: [newGroup],
434+
}, undefined, serializer);
435+
436+
expect(a.groups[0]).toBeInstanceOf(Group);
437+
expect(isReferenceInstance(a.groups[0])).toBe(false);
438+
439+
const b = cast<User>({
440+
id: 1,
441+
groups: [1],
442+
}, undefined, serializer);
443+
444+
expect(b.groups[0]).toBeInstanceOf(Group);
445+
expect(isReferenceInstance(b.groups[0])).toBe(true);
446+
if (isReferenceInstance(b.groups[0])) {
447+
//do something with this instance and fully load it
448+
}
411449
});

0 commit comments

Comments
 (0)