Search code examples
typescripttypescript-compiler-api

`Cannot find name 'Array'` in Typescript Compiler pre-emit diagnostics


I'm using the Typescript Compiler API to do some type-checking in a program I've written. This program is fairly large and includes imports that import other files, etc.

My issue is that, when I create the program using ts.createProgram and look at the pre-emit diagnostics, there are over 1000 entries of the error Cannot find name 'Array'. Additionally, I've noticed that when using certain Typescript features (like the Exclude utility type), even more errors show up in the pre-emit diagnostics. Interestingly, there are never any errors in emitResult.diagnostics

I'm not exactly sure how to provide a reproducible example, but here's the compiler host configuration I'm using. We use Typescript v4.x.x -- I'm not sure if that will affect what features we have available.

import ts from 'typescript';
import {readFileSync} from 'fs';

const defaultCompilerHost = ts.createCompilerHost({});

const customCompilerHost = function (filename, sourceFile) {
  return {
    getSourceFile: (name, languageVersion) => {
      if (name === filename) {
        return sourceFile;
      } else {
        return defaultCompilerHost.getSourceFile(name, languageVersion);
      }
    },
    writeFile: (filename, data) => {},
    getDefaultLibFileName: () => 'lib.d.ts',
    useCaseSensitiveFileNames: () => false,
    getCanonicalFileName: (filename) => filename,
    getCurrentDirectory: () => '',
    getNewLine: () => '\n',
    getDirectories: () => [],
    fileExists: () => true,
    readFile: () => '',
  };
};

const filename = 'file.ts';
const content = readFileSync(filename, { encoding: 'utf8', flag: 'r' });
console.log(content);
const sourceFile = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest);

const program = ts.createProgram([filename], {}, customCompilerHost(filename, sourceFile));
const emitResult = program.emit();
const checker = program.getTypeChecker();

Additionally, the TSConfig file is

{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src", "shared"],
  "exclude": ["node_modules", "metro.config.js", "jest.config.js"]
}

Thanks!


Solution

  • Interestingly, there are never any errors in emitResult.diagnostics

    That will only include the emit diagnostics and not the type checking diagnostics.

    Additionally, the TSConfig file is

    See the first argument to ts.createCompilerHost. You'll want to ensure that's based off the tsconfig.

    there are over 1000 entries of the error Cannot find name 'Array'

    It's probably not finding the lib.d.ts file. You probably see the diagnostic for File 'lib.d.ts' not found. Try changing the code to provide the full path and share the compiler options amongst all the function calls:

    getDefaultLibFileName: () => ts.getDefaultLibFilePath(compilerOptions),
    

    Then implement fileExists, readFile, and getDirectories:

    getDirectories: ts.sys.getDirectories,
    fileExists: ts.sys.fileExists,
    readFile: ts.sys.readFile,