Skip to content

Commit

Permalink
fix(type): add scope in setter code to prevent `variable already decl…
Browse files Browse the repository at this point in the history
…ared` #603 (#606)

- When a tuple definition contained "duplicated" union types like [number|null, number|null], the jitted function couldln't be build as some variable like `oldErrors` were already declared. Probably one block per number|null
  • Loading branch information
lionelhorn authored Aug 11, 2024
1 parent 5ae467e commit 9af344f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 9 deletions.
20 changes: 11 additions & 9 deletions packages/type/src/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1792,16 +1792,18 @@ export function handleUnion(type: TypeUnion, state: TemplateState) {
` : '';

state.addCodeForSetter(`
const oldErrors = state.errors;
if (state.errors) state.errors = [];
//type guard for union
if (false) {} ${lines.join(' ')}
else {
${handleErrors}
${state.assignValidationError('type', 'No valid union member found. Valid: ' + stringifyResolvedType(type))}
{
const oldErrors = state.errors;
if (state.errors) state.errors = [];
//type guard for union
if (false) {} ${lines.join(' ')}
else {
${handleErrors}
${state.assignValidationError('type', 'No valid union member found. Valid: ' + stringifyResolvedType(type))}
}
state.errors = oldErrors;
}
state.errors = oldErrors;
`);
}

Expand Down
69 changes: 69 additions & 0 deletions packages/type/tests/issues/tuples.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { expect, test } from '@jest/globals';
import { cast, validate } from '@deepkit/type';

test('cast literal obj having typed tuple [number | null, number | null] as nested prop', () => {
type MinMax = [number | null, number | null];

class T {
building!: {
area: MinMax
};
}

// const d = JSON.parse('{"building":{"area":[120,null]}}');
const d = {
building: {
area: [120, null],
},
};

const errors = validate<T>(d);
expect(errors.length).toBe(0);

const casted: T = cast<T>(d);

expect(casted.building.area[0]).toBe(120);
expect(casted.building.area[1]).toBe(null);
});

test('cast literal obj to T containing typed tuple', () => {
type SomeData = [string | null, string, string | null];

class T {
tuple!: SomeData;
}

const d = {
tuple: [null, 'z', null],
};

const errors = validate<T>(d);
expect(errors.length).toBe(0);

const casted: T = cast<T>(d);

expect(casted.tuple[0]).toBe(null);
expect(casted.tuple[1]).toBe('z');
expect(casted.tuple[2]).toBe(null);
});

test("cast literal obj having typed tuple [number | null, number | null] as nested prop", () => {
type MinMax = [min: number | null, max: number | null];

class T {
building?: {
area?: MinMax
}
}

// const d = JSON.parse('{"building":{"area":[120,null]}}');

const data: T = cast<T>({
building: {
area: [120, null]
}
});

const errors = validate<T>(data);
expect(errors.length).toBe(0);
});

0 comments on commit 9af344f

Please sign in to comment.