UNPKG

typia

Version:

Superfast runtime validators with only one line

105 lines (95 loc) 2.99 kB
import ts from "typescript"; import { IProject } from "../IProject"; import { TransformerError } from "../TransformerError"; export namespace GenericTransformer { export const scalar = (method: string) => ( programmer: ( project: IProject, ) => ( modulo: ts.LeftHandSideExpression, ) => (type: ts.Type, name: string) => ts.Expression | ts.ArrowFunction, ) => (project: IProject) => (modulo: ts.LeftHandSideExpression) => (expression: ts.CallExpression) => { // CHECK PARAMETER if (expression.arguments.length === 0) throw new TransformerError({ code: `typia.${method}`, message: `no input value.`, }); // GET TYPE INFO const [type, node, generic]: [ts.Type, ts.Node, boolean] = expression.typeArguments && expression.typeArguments[0] ? [ project.checker.getTypeFromTypeNode(expression.typeArguments[0]), expression.typeArguments[0], true, ] : [ project.checker.getTypeAtLocation(expression.arguments[0]!), expression.arguments[0]!, false, ]; if (type.isTypeParameter()) throw new TransformerError({ code: `typia.${method}`, message: `non-specified generic argument.`, }); // DO TRANSFORM return ts.factory.createCallExpression( programmer(project)(modulo)( type, generic ? node.getFullText().trim() : name(project.checker)(type)(node), ), undefined, expression.arguments, ); }; export const factory = (method: string) => ( programmer: ( project: IProject, ) => ( modulo: ts.LeftHandSideExpression, ) => ( type: ts.Type, name: string, init?: ts.Expression, ) => ts.Expression | ts.ArrowFunction, ) => (project: IProject) => (modulo: ts.LeftHandSideExpression) => (expression: ts.CallExpression) => { // CHECK GENERIC ARGUMENT EXISTENCE if (!expression.typeArguments?.[0]) throw new TransformerError({ code: `typia.${method}`, message: `generic argument is not specified.`, }); // GET TYPE INFO const node: ts.TypeNode = expression.typeArguments[0]; const type: ts.Type = project.checker.getTypeFromTypeNode(node); if (type.isTypeParameter()) throw new TransformerError({ code: `typia.${method}`, message: `non-specified generic argument.`, }); // DO TRANSFORM return programmer(project)(modulo)( type, node.getFullText().trim(), expression.arguments[0], ); }; const name = (checker: ts.TypeChecker) => (type: ts.Type) => (node: ts.Node): string => checker.typeToString(type, node, ts.TypeFormatFlags.NodeBuilderFlagsMask); }