TypeScript sees global types that aren't declared in tsconfig's "types" field

Viewed 228

I have a project with multiple tsconfig files because I am building electron app with angular and I would like to have different config for electron code and different config for angular code.

Simplified project structure:

 Foobar //angular app root folder
├─ app //electron app root folder
│  ├─ **/*.ts //multiple folders with .ts files
│  ├─ test
│  │  └─ test.ts
│  └─ tsconfig.json
├─ src //angular code
├─ node_modules
├─ package.json
├─ tsconfig.app.json
├─ tsconfig.json
└─ tsconfig.spec.json

©generated by Project Tree Generator

My problem

Angular code is using jasmine but I would like to use jest to test electron code. For some reason I don't see jest types inside Foobar/app/test/test.ts because they are somehow overriden by jasmine.

For example:

expect(foobar1).toMatchObject(foobar2); //Property 'toMatchObject' does not exist on type 'FunctionMatchers<any>'
//but I can see Jasmine types and methods

but when I change Foobar/app/tsconfig.json

from:

{
  "compilerOptions": {
    "target": "es2018",                               
    "module": "commonjs",                           
    "lib": ["es2018"],                            
    "outDir": "./dist",                             
    "strict": true,                               
    "strictNullChecks": true,                   
    "esModuleInterop": true,                       
    "experimentalDecorators": true,              
    "emitDecoratorMetadata": true,               
    "skipLibCheck": true,                           
    "forceConsistentCasingInFileNames": true,     
  }
}

to:

{
  "compilerOptions": {
    "target": "es2018",                               
    "module": "commonjs",                           
    "lib": ["es2018"],                            
    "outDir": "./dist",                             
    "strict": true,                               
    "strictNullChecks": true,                   
    "esModuleInterop": true,                       
    "experimentalDecorators": true,              
    "emitDecoratorMetadata": true,               
    "skipLibCheck": true,                           
    "forceConsistentCasingInFileNames": true,
    "types": ["jest"] // <---- only this line has been added
  }
}

This solves above toMatchObject error (jest is now used in test.ts file instead of jasmine) but I expected to lose other globals because of what is written in tsconfig documentation but I still see global types that are not included in types array.

For example(Foobar/test/test.ts):

 process.addListener("fail", "idk"); // <-- Argument of type '"fail"' is not assignable to parameter of type 'Signals'.

I expected to lose node types because I only specify jest in the types array but I am still getting autocomplete hints and type errors when calling process (I am not importing process or node in this file, there is just that one line). Why am I still seeing type errors for globals that aren't in the types array in tsconfig.json? Here is a quote from the ts docs:

By default all visible ”@types” packages are included in your compilation. Packages in node_modules/@types of any enclosing folder are considered visible [...] If types is specified, only packages listed will be included in the global scope [...] When you have this option set, by not including a module in the types array it:

  • Will not add globals to your project (e.g process in node, or expect in Jest)

Auto-generated angular tsconfigs

foobar/tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2017",
    "module": "es2020",
    "lib": ["es2018", "dom"],
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
  }
}

Foobar/tsconfig.app.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

Foobar/tsconfig.spec.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [
      "jasmine"
    ]
  },
  "files": [
    "src/test.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

dependencies and devDependencies:

"dependencies": {
    "@angular/animations": "~12.0.2",
    "@angular/common": "~12.0.2",
    "@angular/compiler": "~12.0.2",
    "@angular/core": "~12.0.2",
    "@angular/forms": "~12.0.2",
    "@angular/platform-browser": "~12.0.2",
    "@angular/platform-browser-dynamic": "~12.0.2",
    "@angular/router": "~12.0.2",
    "lodash": "^4.17.21",
    "reflect-metadata": "^0.1.13",
    "rxjs": "~6.6.0",
    "sqlite": "^4.0.23",
    "sqlite3": "^5.0.2",
    "tslib": "^2.1.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.0.2",
    "@angular/cli": "~12.0.2",
    "@angular/compiler-cli": "~12.0.2",
    "@types/jasmine": "~3.6.0",
    "@types/jest": "^26.0.24",
    "@types/lodash": "^4.14.171",
    "@types/node": "^12.11.1",
    "@types/sqlite3": "^3.1.7",
    "electron": "13.1.2",
    "jasmine-core": "~3.7.0",
    "jest": "^27.0.6",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "typescript": "~4.2.3"
  }
0 Answers
Related