Skip to content

Commit

Permalink
fix(type-compiler): make sure type reference resolving skips paramete…
Browse files Browse the repository at this point in the history
…r names

Types can not reference the parameter scope they were used in.

fixes #566
  • Loading branch information
marcj committed May 7, 2024
1 parent eb9ac81 commit 16ba17d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
20 changes: 17 additions & 3 deletions packages/type-compiler/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1895,8 +1895,23 @@ export class ReflectionTransformer implements CustomTransformer {
if (isNodeWithLocals(current) && current.locals) {
const found = current.locals.get(typeName.escapedText);
if (found && found.declarations && found.declarations[0]) {
declaration = found.declarations[0];
break;
/**
* Discard parameters, since they can not be referenced from inside
*
* ```typescript
* type B = string;
* function a(B: B) {}
*
* class A {
* constructor(B: B) {}
* }
* ```
*
*/
if (!isParameter(found.declarations[0])) {
declaration = found.declarations[0];
break;
}
}
}

Expand Down Expand Up @@ -2622,7 +2637,6 @@ export class ReflectionTransformer implements CustomTransformer {
* => function name() {}; name.__type = 34;
*/
protected decorateFunctionDeclaration(declaration: FunctionDeclaration) {

const encodedType = this.getTypeOfType(declaration);
if (!encodedType) return declaration;

Expand Down
27 changes: 27 additions & 0 deletions packages/type-compiler/tests/transpile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,30 @@ test('class typeName', () => {
console.log(res.app);
expect(res.app).toContain(`'StreamApiResponseClass'`);
});

test('resolve type ref', () => {
const res = transpile({
'app': `
class Guest {}
class Vehicle {
constructor(public Guest: Guest) {
}
}
`
});
console.log(res.app);
expect(res.app).toContain(`() => Guest, 'Guest'`);
});

test('resolve type ref2', () => {
const res = transpile({
'app': `
class Guest {}
class Vehicle {
public Guest: Guest;
}
`
});
console.log(res.app);
expect(res.app).toContain(`() => Guest, 'Guest'`);
});
17 changes: 17 additions & 0 deletions packages/type/tests/serializer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
Reference,
ReflectionKind,
SignedBinaryBigInt,
stringifyResolvedType,
Type,
TypeProperty,
TypePropertySignature,
Expand Down Expand Up @@ -1373,3 +1374,19 @@ test("parcel search input deserialization", async () => {
expect(search?.ad?.attributes?.buildingSurface).toBe(92);
expect(search?.ad?.location.hasCoords()).toBeTruthy();
});

test('skip parameter name resolving', () => {
class Guest {
constructor(public id: number) {
}
}

class Vehicle {
constructor(public Guest: Guest) {
}
}

console.log(stringifyResolvedType(typeOf<Vehicle>()));

expect(cast<Vehicle>({ Guest: { id: '1' } })).toEqual(new Vehicle(new Guest(1)));
});

0 comments on commit 16ba17d

Please sign in to comment.