or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdjest-extensions.mdmonorepo-utilities.mdresolver-testing.mdserver-mocking.mdtypescript-validation.md
tile.json

typescript-validation.mddocs/

TypeScript Validation

Utilities for validating and compiling TypeScript code generated by GraphQL Codegen plugins, with comprehensive error reporting and customizable compiler options.

Capabilities

validateTs Function

Validates TypeScript code by parsing and type-checking plugin output using the TypeScript compiler API. Essential for ensuring generated code is syntactically correct and type-safe.

/**
 * Validates TypeScript code by parsing and type-checking plugin output
 * @param pluginOutput - The plugin output content to validate (string or PluginOutput object)
 * @param options - TypeScript compiler options (optional, has comprehensive defaults)
 * @param isTsx - Whether to treat as TSX file (default: false)
 * @param isStrict - Enable strict mode compilation (default: false) 
 * @param suspenseErrors - Array of error strings to suppress (default: [])
 * @param compileProgram - Whether to create full TypeScript program for validation (default: false)
 * @throws Error or AggregateError for validation failures
 */
function validateTs(
  pluginOutput: Types.PluginOutput,
  options?: CompilerOptions,
  isTsx?: boolean,
  isStrict?: boolean,
  suspenseErrors?: string[],
  compileProgram?: boolean
): void;

Default Compiler Options:

  • noEmitOnError: true - Fail validation on compilation errors
  • noImplicitAny: true - Require explicit type annotations
  • moduleResolution: ModuleResolutionKind.NodeJs - Use Node.js module resolution
  • experimentalDecorators: true - Enable decorator support
  • target: ScriptTarget.ES5 - Compile to ES5 for broad compatibility
  • jsx: JsxEmit.React - React JSX transformation
  • allowJs: true - Allow JavaScript files
  • skipLibCheck: true - Skip type checking of declaration files
  • module: ModuleKind.ESNext - Use modern ES modules

Usage Examples:

import { validateTs } from "@graphql-codegen/testing";
import { Types } from '@graphql-codegen/plugin-helpers';

// Basic validation
const generatedCode = `
  export interface User {
    id: string;
    name: string;
  }
`;

validateTs(generatedCode);

// Validation with custom options
validateTs(generatedCode, {
  strict: true,
  target: ScriptTarget.ES2020
});

// Validate plugin output object
const pluginResult: Types.ComplexPluginOutput = {
  prepend: ['import { GraphQLResolveInfo } from "graphql";'],
  content: 'export type QueryResolvers = { users: Resolver<User[]>; };',
  append: []
};

validateTs(pluginResult);

// TSX validation
const tsxCode = `
  const Component = () => <div>Hello</div>;
`;

validateTs(tsxCode, {}, true); // isTsx = true

// Strict mode validation
validateTs(generatedCode, {}, false, true); // isStrict = true

compileTs Function

Compiles TypeScript code and validates compilation with full program creation and emit checking. More comprehensive than validateTs for complex validation scenarios.

/**
 * Compiles TypeScript code and validates compilation
 * Creates a full TypeScript program and attempts compilation
 * @param contents - TypeScript source code to compile
 * @param options - TypeScript compiler options (optional, has defaults similar to validateTs)
 * @param isTsx - Whether to treat as TSX (default: false)
 * @param openPlayground - Open TypeScript playground on error for debugging (default: false)
 * @throws Error for compilation failures
 */
function compileTs(
  contents: string,
  options?: CompilerOptions,
  isTsx?: boolean,
  openPlayground?: boolean
): void;

Key Differences from validateTs:

  • Always creates a full TypeScript program
  • Performs emit checking in addition to parsing
  • Can open TypeScript playground for debugging compilation errors
  • Optimized for comprehensive compilation validation rather than quick syntax checking

Usage Examples:

import { compileTs } from "@graphql-codegen/testing";

// Basic compilation validation
const complexCode = `
  import { GraphQLResolveInfo } from 'graphql';
  
  export type QueryResolvers<ContextType = any> = {
    users?: Resolver<User[], {}, ContextType>;
  };
  
  type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
    | ResolverFn<TResult, TParent, TContext, TArgs>;
`;

compileTs(complexCode);

// With TypeScript playground debugging
try {
  compileTs(problematicCode, {}, false, true);
} catch (error) {
  // Playground will open if compilation fails
  console.error('Compilation failed:', error.message);
}

// TSX compilation
const componentCode = `
  import React from 'react';
  
  interface Props {
    users: User[];
  }
  
  export const UserList: React.FC<Props> = ({ users }) => (
    <ul>
      {users.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
`;

compileTs(componentCode, {}, true); // isTsx = true

Error Handling and Debugging

Both validation functions provide detailed error reporting:

Error Filtering:

  • Automatically filters out "Cannot find module" errors (common in isolated validation)
  • Supports custom error suppression via suspenseErrors parameter
  • Aggregates multiple errors into AggregateError when multiple issues exist
  • Single errors throw standard Error objects with detailed TypeScript diagnostic information

Error Information:

  • Line and character position of errors
  • Full diagnostic messages from TypeScript compiler
  • Source code context showing the problematic line
  • Detailed error descriptions with suggested fixes

Environment Variables:

  • SKIP_VALIDATION: Set to any truthy value to skip validation entirely (useful for CI/debugging scenarios when you want to bypass TypeScript compilation checks)

Usage with Generated Code:

// Validate resolver plugin output
const resolverOutput = await resolverPlugin(schema, [], config);

// Merge with TypeScript base types
const mergedContent = mergeOutputs([
  await typescriptPlugin(schema, [], {}), 
  resolverOutput
]);

// Validate complete generated code
validateTs(mergedContent, {
  strict: true,
  noImplicitAny: true
});