Skip to content

Commit

Permalink
fix(type): make sure methods are not part of deserialization/type gua…
Browse files Browse the repository at this point in the history
…rd union resolver

This basically excluded methods/methodSignatures when trying to run deserialization and type guards in deserialization mode.
  • Loading branch information
marcj committed Feb 27, 2024
1 parent 1ce87cd commit eb08a73
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/http/tests/router.spec.ts
Expand Up @@ -1733,7 +1733,8 @@ test('http body deep optional union', async () => {
originalAd: AdTitleAndBasicAttributes | null = null;
ad: AdTitleAndBasicAttributes | null = null;

constructor() {
hasAd() {
return !!this.ad;
}
}

Expand Down
5 changes: 5 additions & 0 deletions packages/type/src/serializer.ts
Expand Up @@ -1339,6 +1339,11 @@ export function typeGuardObjectLiteral(type: TypeObjectLiteral | TypeClass, stat

if (member.name === 'constructor') continue;

if (state.target === 'deserialize' && (member.kind === ReflectionKind.method || member.kind === ReflectionKind.methodSignature)) {
// methods can not be part of serialized data, so we skip them.
continue;
}

const readName = member.kind === ReflectionKind.methodSignature || member.kind === ReflectionKind.method
? getNameExpression(member.name, state)
: getNameExpression(state.isDeserialization ? state.namingStrategy.getPropertyName(member, state.registry.serializer.name) : memberNameToString(member.name), state);
Expand Down
51 changes: 51 additions & 0 deletions packages/type/tests/serializer.spec.ts
Expand Up @@ -1220,3 +1220,54 @@ test('union with optional property', () => {
expect(a).toEqual({ type: 'a', value: undefined });
}
});

test("parcel search input deserialization", async () => {
class GeoLocation {
locality?: string;
postalCode?: string;

hasCoords() {
return true;
}
}

interface AdTitleAndBasicAttributes {
title: string;
attributes: {
plotSurface?: number,
buildingSurface: number,
ges?: string,
energyRate?: string,
};
location: GeoLocation,
}

class ParcelSearchParams {
ad: AdTitleAndBasicAttributes | null = null;
}

const data: any = {
"ad": {
"title": "Maison 4 pièces 92 m²",
"attributes": {
"buildingSurface": 92,
"energyRate": "D",
"ges": "E"
},
"location": {
"locality": "Paris",
"postalCode": "75000"
}
}
} as any;

const location = cast<GeoLocation>(data.ad.location);
expect(location).toBeInstanceOf(GeoLocation);
expect(location.locality).toBe("Paris");

const search = cast<ParcelSearchParams>(data);
expect(search.ad).not.toBeUndefined();
expect(search.ad!.location).toBeInstanceOf(GeoLocation);
expect(search?.ad?.attributes?.buildingSurface).toBe(92);
expect(search?.ad?.location.hasCoords()).toBeTruthy();
});

0 comments on commit eb08a73

Please sign in to comment.