Skip to content

Commit

Permalink
Add support of 'extends' property in tsconfig.json (#33)
Browse files Browse the repository at this point in the history
* Move code related to reading tsconfig.json into a function

* Make getCompilerOptions options support "extends" prop in tsconfig

* Add a test for extends functionality

* Simplify base tsconfig

* Simplify tsconfig

* Remove not important comment

* Run prettier
  • Loading branch information
bijela-gora committed Mar 13, 2023
1 parent e5f21bd commit b1f1bd4
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 36 deletions.
12 changes: 4 additions & 8 deletions check.js
@@ -1,13 +1,14 @@
import { dirname, basename, join, relative } from 'path'
import { existsSync, promises as fs } from 'fs'
import { promises as fs } from 'fs'
import { createRequire } from 'module'
import { fileURLToPath } from 'url'
import { createSpinner } from 'nanospinner'
import { location } from 'vfile-location'
import { Worker } from 'worker_threads'
import pico from 'picocolors'
import glob from 'fast-glob'
import JSON5 from 'json5'

import { getCompilerOptions } from './get-compiler-options.js'

let require = createRequire(import.meta.url)

Expand Down Expand Up @@ -74,12 +75,7 @@ export async function check(
let spinner = createSpinner('Check types', { stream: stderr })
spinner.start()

let compilerOptions
let tsconfigPath = join(cwd, 'tsconfig.json')
if (existsSync(tsconfigPath)) {
let tsconfig = JSON5.parse(await fs.readFile(tsconfigPath))
compilerOptions = tsconfig.compilerOptions
}
let compilerOptions = getCompilerOptions(cwd)

let all = await glob(globs, { cwd, ignore: ['node_modules'], absolute: true })

Expand Down
29 changes: 4 additions & 25 deletions create-program.js
Expand Up @@ -6,34 +6,13 @@ let require = createRequire(import.meta.url)

const TS_DIR = dirname(require.resolve('typescript'))

const DEFAULT = {
allowSyntheticDefaultImports: true,
strictFunctionTypes: false,
noUnusedParameters: true,
noImplicitReturns: true,
moduleResolution: 'NodeJs',
noUnusedLocals: true,
stripInternal: true,
allowJs: true,
module: 'esnext',
strict: true,
noEmit: true,
jsx: 'react'
}

export function createProgram(files, opts = DEFAULT) {
opts.moduleResolution = 'node'

let { options, errors } = ts.convertCompilerOptionsFromJson(opts, './')

if (errors.length) {
throw errors
}
export function createProgram(files, options) {
options.moduleResolution = ts.ModuleResolutionKind.NodeJs

if (options.lib) {
options.lib.forEach(path => {
for (let path of options.lib) {
files.push(join(TS_DIR, path))
})
}
options.lib.length = 0
}

Expand Down
33 changes: 33 additions & 0 deletions get-compiler-options.js
@@ -0,0 +1,33 @@
import ts from 'typescript'

const DEFAULT_OPTIONS = ts.convertCompilerOptionsFromJson(
{
allowSyntheticDefaultImports: true,
strictFunctionTypes: false,
noUnusedParameters: true,
noImplicitReturns: true,
moduleResolution: 'NodeJs',
noUnusedLocals: true,
stripInternal: true,
allowJs: true,
module: 'esnext',
strict: true,
noEmit: true,
jsx: 'react'
},
'./'
).options

export function getCompilerOptions(cwd, configName = 'tsconfig.json') {
let configFileName = ts.findConfigFile(cwd, ts.sys.fileExists, configName)
if (configFileName === undefined) {
return DEFAULT_OPTIONS
}
let configFile = ts.readConfigFile(configFileName, ts.sys.readFile)
let parsedCommandLine = ts.parseJsonConfigFileContent(
configFile.config,
ts.sys,
cwd
)
return parsedCommandLine.options
}
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -21,7 +21,6 @@
},
"dependencies": {
"fast-glob": "^3.2.12",
"json5": "^2.2.3",
"nanospinner": "^1.1.0",
"picocolors": "^1.0.0",
"vfile-location": "^4.0.1"
Expand Down
3 changes: 1 addition & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions test/__snapshots__/check.test.js.snap
Expand Up @@ -91,6 +91,13 @@ exports[`loads custom tsconfig.json 1`] = `
"
`;

exports[`loads custom tsconfig.json with extends property 1`] = `
"- Check types
✔ Check types
✔ index.errors.ts
"
`;

exports[`supports simple cases 1`] = `
"- Check types
✔ Check types
Expand Down
4 changes: 4 additions & 0 deletions test/check.test.js
Expand Up @@ -58,6 +58,10 @@ it('loads custom tsconfig.json', async () => {
expect(await good('tsconfig')).toMatchSnapshot()
})

it('loads custom tsconfig.json with extends property', async () => {
expect(await good('tsconfig-with-extends')).toMatchSnapshot()
})

it('accepts files', async () => {
expect(await good('negative', 'b.*')).toMatchSnapshot()
})
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/tsconfig-with-extends/index.errors.ts
@@ -0,0 +1,6 @@
declare const a: number | null

// THROWS Type 'number | null' is not assignable to type 'number'.
export const b: number = a

// This file checks whether the compiler performs strictNullChecks if it is enabled in the config file specified via extends
5 changes: 5 additions & 0 deletions test/fixtures/tsconfig-with-extends/tsconfig.base.json
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"strictNullChecks": true
}
}
9 changes: 9 additions & 0 deletions test/fixtures/tsconfig-with-extends/tsconfig.json
@@ -0,0 +1,9 @@
{
// tsconfig should support extends
"extends": "./tsconfig.base.json",
"compilerOptions": {
"noUnusedLocals": false,
"target": "ES5",
"moduleResolution": "Node"
}
}

0 comments on commit b1f1bd4

Please sign in to comment.