Thread viewer for Bluesky
1import ts from 'typescript';
2import { readFileSync } from "node:fs";
3import { dirname, resolve } from "node:path";
4
5const configPath = 'tsconfig.json';
6
7let incrementalProgram;
8
9export function runTypecheck() {
10 let configFilePath = ts.findConfigFile(process.cwd(), ts.sys.fileExists, configPath);
11 let configFile = ts.readConfigFile(configFilePath, ts.sys.readFile);
12
13 if (configFile.error) {
14 throw new Error(ts.formatDiagnosticsWithColorAndContext([configFile.error], {
15 getCurrentDirectory: ts.sys.getCurrentDirectory,
16 getCanonicalFileName: x => x,
17 getNewLine: () => ts.sys.newLine
18 }));
19 }
20
21 let parsedConfig = ts.parseJsonConfigFileContent(
22 configFile.config,
23 ts.sys,
24 dirname(configFilePath),
25 { noEmit: true, incremental: true, tsBuildInfoFile: ".tsbuildinfo" },
26 configFilePath
27 );
28
29 let host = ts.createIncrementalCompilerHost(parsedConfig.options);
30
31 let program = ts.createIncrementalProgram({
32 rootNames: parsedConfig.fileNames,
33 options: parsedConfig.options,
34 host,
35 oldProgram: incrementalProgram && incrementalProgram.getProgram()
36 });
37
38 incrementalProgram = program;
39
40 // TODO
41 // https://github.com/microsoft/TypeScript/pull/31432
42 // https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API/8e7d4bd1c85622cf078303075cbdf95a0a1bc8ab
43
44 let diags = ts
45 .getPreEmitDiagnostics(program.getProgram())
46 .concat(program.getSemanticDiagnostics?.() ?? []);
47
48 let formatHost = {
49 getCurrentDirectory: ts.sys.getCurrentDirectory,
50 getCanonicalFileName: x => x,
51 getNewLine: () => ts.sys.newLine
52 };
53
54 let ok = (diags.length === 0);
55 let text = ts.formatDiagnosticsWithColorAndContext(diags, formatHost);
56
57 return { ok, text };
58}