tsconfig.jsonを読み込んでCompilerOptions を生成する方法


TypeScriptのCompiler APIを使うときCompilerOptionsが必要になることがある。これはtsconfig.jsoncompilerOptionsの内容である。これをTypeScript Compile APIを使うときの値にしたい。

しかし、tsconfig.jsonを直接読み込んでもextendsされていたり、そもそもCompileOptionsにしたときに使う値を違うものがあるため、期待した内容をではない。

調べたところgetParsedCommandLineOfConfigFileあたりを使うのが一番簡単にCompilerOptionsが取得できそうだった。

具体的には下記のような関数を用意して使った。

function readCompilerOptions(filename: string): ts.CompilerOptions {
  const tsconfigValue = ts.getParsedCommandLineOfConfigFile(
    filename,
    {},
    ts.sys as any,
  );
  return tsconfigValue?.options || {};
}

補足

参考にした場所

この方法はtscの処理を追ってCompileOptionsを取り出す仮定で、一番使いやすそうな場所を抜粋したものです。

    export function parseConfigFileWithSystem(configFileName: string, optionsToExtend: CompilerOptions, watchOptionsToExtend: WatchOptions | undefined, system: System, reportDiagnostic: DiagnosticReporter) {
        const host: ParseConfigFileHost = <any>system;
        host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic);
        const result = getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, /*extendedConfigCache*/ undefined, watchOptionsToExtend);
        host.onUnRecoverableConfigFileDiagnostic = undefined!; // TODO: GH#18217
        return result;
    }

SystemをParseConfigFileHostとして使っている。あとは追加のオプションなので空でわたしています。

CompilerOptionsとtsconfigで違う値になる部分の例

たとえばjsxであればenumになっているので数値になる。tsconfig.json上では "react"のように文字列指定をする。

interface CompilerOptions {
   // (略)
   jsx?: JsxEmit | ts.JsxEmit;
   // (略)
}

const enum JsxEmit {
    None = "None",
    Preserve = "Preserve",
    ReactNative = "ReactNative",
    React = "React"
}