TypeScript: `skipLibCheck: true` is ignored when package's `types` field points to a `.ts` file (not a `.d.ts` declaration file)

TypeScript Version: 3.9.7

Search Terms:

skipLibCheck is ignored skipLibCheck not working

Code

N/A

Expected behavior:

TypeScript should ignore type errors in node_modules (or skip reporting them? I’m not sure exactly what skipLibCheck does).

Actual behavior:

When skipLibCheck is set to true, TS will still have type errors in packages in node_modules. It seems that this is the case if a package’s types field in the package’s tsconfig.json file points to a .ts file instead of a .d.ts file.

For example, in my project that consumes the lume package, there are type errors like these:

node_modules/lume/src/html/WithUpdate.ts:132:13 - error TS2784: 'get' and 'set' accessors cannot declare 'this' parameters.

132     get props(this: any): any {
                  ~~~~~~~~~

node_modules/lume/src/core/Utility.ts:5:10 - error TS7030: Not all code paths return a value.

5 function applyCSSLabel(value: any, label: any) {
           ~~~~~~~~~~~~~

As you can see the path in the errors are in node_modules. The lume package’s types field points to its src/index.ts file, and hence all the types in that package are based on .ts files instead of .d.ts files.

Playground Link:

N/A


Maybe I misunderstand what skipLibCheck does. What should it do exactly?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 17
  • Comments: 27 (6 by maintainers)

Most upvoted comments

This issue has been marked ‘Working as Intended’ and has seen no recent activity. It has been automatically closed for house-keeping purposes.

This issue, together with https://github.com/microsoft/TypeScript/issues/38538, is what we’re seeing as well.

The core seems to be that that TypeScript checks imported .ts files regardless of whether they are source files or external dependencies, and options like include, exclude or skipLibCheck don’t have any effect on this (rightfully so but that doesn’t make the issue go away 😄).

We think that TypeScript just crawls imports inside files that match include / exclude and that it then runs a typecheck on everything it finds:

  • .ts files are checked unconditionally
  • .d.ts files are checked if not disabled via skipLibCheck

The first point is a problem – we don’t want to see errors from node_modules or generally from .ts files that are not source files of the current project.

I acknowledge that skipLibCheck might not be possible to amend (though intuitively, node_modules/some-plain-ts-library is a library) but there should be some way to prevent it. There is currently no workaround as far as I know.


Some context: besides the use case reported by the OP ("types" pointing to .ts), there’s another one.

Modern frameworks like Next.js, Gatsby, CRA and others process TypeScript “natively” so it’s actually better not to transpile .ts and leave this job on webpack / Babel / esbuild / whatever the transpilation pipeline that framework uses. This leads to a new world where .js + .d.ts files don’t exist on the disk – for example, in our Next.js project, we never run full transpilation, that’s up to the next dev / next build to produce some .js bundles.

We’re using TypeScript as a “linter” only, i.e., tsc --noEmit.

I think one would intuitively expect no errors from inside node_modules (unless it is critical, like invalid syntax?) when skipLibCheck is true, because ultimately the dependency code is plain JavaScript (or will end up as plain JavaScript).

For example, the Webpack build in the consumer app works fine, it pulls in the non-.ts files from dist/, and the app works fine.

The types in the lume package work just fine when that repo is cloned and build with tsc. The errors I see are in another project that just installed lume and presumably uses a different version of tsc. Intuition here expects the code to be fine.

How do we assert to tsc that everything is fine and to strictly ignore those type errors in node_modules?

So what is the status here? I understand that all of the existing settings are working as intended (ie: include, exclude, skipLibCheck).

But for the increasingly common use case of using tsc --no-emit for linting purposes (rather than compiling), there doesn’t appear to be any workable solution. Should a new issue be made for that? Or is this considered a “wont-fix”?

Just hit this and have no idea how to resolve, no changes to any tsconfig files or updates to typescript or the problematic library but the build is throwing this:

../node_modules/native-base/src/hooks/useContrastText.ts:43:52
Type error: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.

  41 |     bgThemeColorVariant &&
  42 |     themeColorsThresholdShades[bgThemeColorVariant]
> 43 |       ? getContrastThemeColor(bgThemeColorVariant, bgShade)
     |                                                    ^
  44 |       : getAccessibleContrastColor(
  45 |           contrastThreshold,
  46 |           trueDarkText,
info  - Checking validity of types .task: Failed to run task "web-build": exit status 1

What’s the advised way to go about this? Surely it can’t be changing all imports to requires that would result a huge diff and seems backwards. This is working fine on another branch and it seems to only be this file that’s failing.

And yes "skipLibCheck": true, is there and exclude node_modules is there, has been working fine for months.

We are interested in making .d.ts file generation less of a hassle, but patching skipLibCheck for the use-case of shipping .ts files to get around the issues described is not the direction we want to take.

I faced this same issue past friday. It’s even weird because the library we used had a few TS rules off in its package.json, but at the moment it was imported in the project, it ignored the library config and used our main project config, which obviously will fail.

For now, the only workaround we found was to replace the import for that lib with a require.

I have the same issue with "typescript": "^4.7.4"

$ npx tsc --skipLibCheck true
node_modules/react-dropzone-uploader/dist/Dropzone.tsx:504:44 - error TS2571: Object is of type 'unknown'.

504       console.error('Error Upload Params', e.stack)
                                               ~
Found 1 error in node_modules/react-dropzone-uploader/dist/Dropzone.tsx:504

It was working with previous version of typescript (4.5)

The problem also occurs when the types field in package.json refers to a .d.ts file and there is a .d.ts.map present which links to the .ts source.

Typescript tries to recompile the source in that case, which seems wrong.

@RyanCavanaugh I agree.

I intuitively thought that exclude would do this (it seems to be a common try by people hitting this issue) but I now understand that it behaves differently so that’s not a way.

I’d say that “my code” is everything under the current folder (where tsconfig.json is) minus node_modules. So <project>/../lib/*.ts is not my source code, neither is <project>/node_modules/abc/index.ts.

I imagine it would still be possible to explicitly include those if one wants, like this:

{
  "include": "node_modules/abc/*.ts"
}

Do you see any glaring holes in this or could it work?

If you’re using webpack with the ForkTsCheckerWebpackPlugin, I found a pretty weird solution which makes the error disappear:

new ForkTsCheckerWebpackPlugin({
    ...,
    issue: {
        include: [
            { file: '**/*' }
        ]
    }
})

So just including everything makes it work for me again.

Tangentially related but Deno 1.17 now supports --no-check=remote:

The --no-check=remote option was added to help with this. When this flag is passed, the program will be type checked as a whole, but any diagnostics that are coming from a remote module will be discarded. If there are no local diagnostics, your program will run.

Feels similar in spirit to this issue.