'Validate typescript definition files for errors programatically

I am generating typescript definition files programmatically. Sometimes an incorrect definition file will be generated from user error. This cannot be changed and is irrelevant.

export type Test = {
    prop: number
}

export interface Example {
  test: string;               // Error since not of type Test
  [k: string]: Test; 
}

I am trying to programmatically check this definition file to see if I get errors. For example, if I create a file for testing purposes with a single import;

import * as TestImport from './example';

and then use the typescript compiler from command line, I will get an error as expected;

$ npx tsc --noEmit test.ts
$ error TS2411: Property 'test' of type 'string' is not assignable to 'string' index type 'Test'.

5     test: string;
      ~~~~~~~~~~~~~

This is a good step, and perhaps as a fall back I will look into simply using npx programmatically.

However, for now I am trying to use tsc directly, but I am getting no error on compilation;

import { transpile } from "typescript";
import { readFile } from "fs/promises"

const data: string = (await readFile(`./example.ts`)).toString();
transpile(data, { strict: true });

I tried using transpileModule too but nothing. I also tried dynamic imports out of desperation, but runtime imports obviously don't influence typescript defintions.

I'm stumped as to why tsc from the command line seems to find this import issue with definitions but transpile does not. Is transpile even the correct method to use? Am I missing compilation options? Do I need to write a basic custom compiler?



Solution 1:[1]

I've been fiddling around with this yesterday to test type challenge solutions and here's what I found so far.

Create a new Program:

import ts from "typescript";

const program = ts.createProgram({
    // ...
});

Provide the compiler options:

const program = ts.createProgram({
    options: { ... },
});

Provide the entry point:

const program = ts.createProgram({
    // ...
    rootNames: ["./check-this-file.ts"],
});

Then call emit and check the diagnostics:

const { diagnostics } = program.emit();

It will be an array of Diagnostic objects which you can log and see what's included in there (diagnostic message, location, code, etc).

A pretty basic custom compiler if you ask me ?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hittingonme