Skip to content

Commit

Permalink
fix(type-compiler): support ReceiveType in arrow function with body e…
Browse files Browse the repository at this point in the history
…xpression

This makes sure the following works correctly:

```typescript
(type?: ReceiveType) => (v: any) => {
    type = resolveReceiveType(type);
    // ...
};
```
  • Loading branch information
marcj committed May 8, 2024
1 parent 0136971 commit 3c66064
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
14 changes: 12 additions & 2 deletions packages/type-compiler/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ import { knownLibFilesForCompilerOptions } from '@typescript/vfs';
import { debug, debug2 } from './debug.js';
import { ConfigResolver, getConfigResolver, MatchResult, ReflectionConfig, ReflectionConfigCache, reflectionModeMatcher, ResolvedConfig } from './config.js';


const {
visitEachChild,
visitNode,
isPropertyAssignment,
isArrayTypeNode,
isArrowFunction,
isBlock,
isCallExpression,
isCallSignatureDeclaration,
isClassDeclaration,
Expand All @@ -111,6 +111,7 @@ const {
isConstructSignatureDeclaration,
isEnumDeclaration,
isExportDeclaration,
isExpression,
isExpressionWithTypeArguments,
isFunctionDeclaration,
isFunctionExpression,
Expand Down Expand Up @@ -1105,7 +1106,16 @@ export class ReflectionTransformer implements CustomTransformer {
this.f.createToken(ts.SyntaxKind.EqualsToken),
this.f.createIdentifier('undefined'),
));
const body = node.body ? this.f.updateBlock(node.body as Block, [reset, ...(node.body as Block).statements]) : undefined;

// convert expression into statements array
let body = node.body && isBlock(node.body) ? node.body : undefined;
let bodyStatements: Statement[] = node.body && isBlock(node.body) ? [...node.body.statements] : [];
if (node.body) {
if (isExpression(node.body)) {
bodyStatements = [this.f.createReturnStatement(node.body)];
}
body = this.f.updateBlock(node.body as Block, [reset, ...bodyStatements]);
}

if (isArrowFunction(node)) {
return this.f.updateArrowFunction(node, node.modifiers, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, body as ConciseBody) as T;
Expand Down
15 changes: 15 additions & 0 deletions packages/type-compiler/tests/transpile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,3 +536,18 @@ test('resolve type ref2', () => {
console.log(res.app);
expect(res.app).toContain(`() => Guest, 'Guest'`);
});

test('ReceiveType arrow function', () => {
const res = transpile({
'app': `
export const typeValidation = <T>(type?: ReceiveType<T>): ValidatorFn => (control: AbstractControl) => {
type = resolveReceiveType(type);
const errors = validate<T>(control.value)
console.log(errors)
return errors.length ? {validation: errors[0]} : null
}
`
});
console.log(res.app);
expect(res.app).toContain(`exports.typeValidation.Ω = undefined; return __assignType((control) =>`);
});
13 changes: 12 additions & 1 deletion packages/type/tests/receive-type.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, test } from '@jest/globals';
import { ReceiveType, resolveReceiveType, typeOf } from '../src/reflection/reflection.js';
import { ReflectionKind, Type } from '../src/reflection/type.js';
import { ReflectionOp } from '@deepkit/type-spec';
import { validates } from '../src/validator.js';

test('typeOf', () => {
const type = typeOf<string>();
Expand Down Expand Up @@ -97,3 +97,14 @@ test('class constructor multiple', () => {
expect(aString.type1).toMatchObject({ kind: ReflectionKind.string });
expect(aString.type2).toMatchObject({ kind: ReflectionKind.number });
});

test('function with ReceiveType return expression', () => {
const typeValidation = <T>(type?: ReceiveType<T>) => (value: any) => {
type = resolveReceiveType(type);
return validates(value, type);
}

const validateString = typeValidation<string>();
expect(validateString('hello')).toBe(true);
expect(validateString(2)).toBe(false);
});

0 comments on commit 3c66064

Please sign in to comment.