0

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?

1 Answer 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 😉

Sign up to request clarification or add additional context in comments.

3 Comments

Humm, I tried this and still get no errors in the diagnostics - even with the same ts configuration as the CLI command uses.
Is the entry point correct?
I know it's been a while, but have you tried running ts.getPreEmitDiagnostics(program)? My diagnostic array is empty, but getPreEmitDiagnostics does return the expected validation errors

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.