microsoft / microsoft/TypeScript

Node module dependencies that use a triple-slash directive to reference libs poison the global scope

Open
#33,111 5 comments 20 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

In Discussion Suggestion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

TypeScript Version: 2.x, 3.x

Search Terms: lib.dom.d.ts pollutes global scope, name is defined as never, event is defined as Event | undefined

See: https://github.com/AaronFriel/is-test/blob/4e235decffdfd3c137ea066f8462d57d2fc8d0f2/src/index.ts at the commit hash linked.

Expected behavior:

Given a tsconfig.json with lib: [], I would expect the following code to fail to build due to $variable not defined errors:

import is from '@sindresorhus/is';

function main() {
  console.log(name);
  console.log(event);
  console.log(caches);
  console.log(applicationCache);
  console.log(parent);
}

Actual behavior:

See: https://github.com/AaronFriel/is-test/blob/master/src/index.ts for a particularly egregious example of this. It builds without any type errors. When running npm run start, it will throw a runtime error on the first console.log. If you remove that line, the next one fails, and so on, for the next 700+ lines.

General purpose libraries often need to be written to handle multiple versions of ES (ES5, ES6, ES7...) and multiple host environments (e.g.: DOM, ScriptHost, WebWorker). But right now they are faced with a choice:

A: Use a triple slash directive to import types that they use, and poison the user's global scope, causing nearly one thousand variable names to be silently accepted as defined without any type checker errors.

B: Remove the triple slash directives and require that users use the --skipLibCheck option or equivalent in their config file or include the required libs in their compiler options. Otherwise the library will fail to type check.

This is a choice that library authors would quite reasonably not want to make.

Potential solutions:

  1. Triple slash directives should import types only in dependencies.

    This seems tricky to implement, I think.

  2. There should be a types-only version of the major lib files, so that general-purpose utility packages can reference those instead.

    This seems less tricky: extract all the types from the dom lib a new dom-types lib, and use a directive to reference the types. Then, library authors can triple-slash reference dom-types and get only the types. Has the advantage of not causing any compatibility issues, and library authors can opt in to the types-only package.

  3. ???

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the behavior with the linked src/index.ts example and a tsconfig.json using lib: []; inspect how triple-slash directives and lib.dom.d.ts affect dependency type checking. Done means the undeclared globals in the example produce type errors without requiring library authors to remove their referenced types; no specific test file is named.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.