Skip to content

lib.dom.d.ts seems to not be referenced when any file in the compilation contains no-default-lib=true triple slashΒ #57524

Open

Description

πŸ”Ž Search Terms

no-default-lib lib dom ignored cannot resolve HTMLElement paths

πŸ•— Version & Regression Information

This is an unintuitive error that took me a long time to pin down.

⏯ Playground Link

No response

πŸ’» Code

Given the following 3 files:

worker.d.ts

/// <reference no-default-lib="true"/>
/// <reference lib="webworker" />
/// <reference lib="esnext" />

export declare class MyWorker {}

library.d.ts

import type { MyWorker } from "./worker";

export interface Type1 {
  worker: MyWorker;
}

app.d.ts

interface App {
  prop: HTMLElement;
}

tsconfig.json

{
  "compilerOptions": {
    "lib": [ "ES2020", "DOM" ],
  },
}

πŸ™ Actual behavior

An error occurs in the app.d.ts file

Cannot find name 'HTMLElement'.ts(2304)

πŸ™‚ Expected behavior

Any of the following:

  • A better error message inside the app.d.ts file
  • an error in the tsconfig
  • a better error message when using --traceResolution

Suggesting a reason for why lib: [ "DOM" ] in the tsconfig file is ignored.

Its also possible this is incorrect behaviour, however the docs say document that the use case for no-default-lib is for files that do not include the default library, rather than those (like in my case) that wanted to ignore the default libraries included via the tsconfig.json.

Additional information about the issue

This bug is really here as a helpful hint in case anyone else runs into this same issue. Its particularly difficult to debug the issue, as app.d.ts has no references to anything. In my real project, the situation is a bit more complicated, and it took me a long time to figure out that this was the issue.

As a side note, what is the best way to do typings for a web worker file within an existing project? At the moment, I'll be adding a separate tsconfig file for the specific web worker, and exclude that file from the main tsconfig, EDIT: This doesn't actually work, as each separate tsconfig file cannot include files from the other when composite is true.

Activity

  1. changed the title [-]lib.dom.d.ts seems to not be referenced when any file contains no-default-lib=true triple slash[/-] [+]lib.dom.d.ts seems to not be referenced when any file in the compilation contains no-default-lib=true triple slash[/+] on Feb 24, 2024
  2. RyanCavanaugh commented on Feb 25, 2024

    @RyanCavanaugh
    Member

    I don't think it was intentional that this directive causes an explicitly-set lib setting to be ignored. Sheetal Nandi (@sheetalkamat) ?

  3. sheetalkamat commented on Feb 26, 2024

    @sheetalkamat
    Member

    I think this was intentional per https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-no-default-libtrue means it is as if you passed noLib atleast per documentation.

  4. JakeYallop commented on Feb 26, 2024

    @JakeYallop
    Author

    The docs say:

    This directive instructs the compiler to not include the default library (i.e. lib.d.ts)

    So by the docs, maybe this is correct behaviour. However, if I change "app.d.ts" to

    /// <reference lib="dom" />
    
    interface App {
      prop: HTMLElement;
    }

    Then the error goes away. this seems to be inconsistent - what is the difference between referencing the library via lib: [ "DOM" ] in tsconfig vs using /// <reference lib="dom" /> in a file?

    As a side note, if I create "other.d.ts"

    interface Other {
      prop: HTMLElement;
    }

    there are no longer any errors - so it seems like the triple slash is including the types, despite it not being possible to include them via the tsconfig.

  5. sheetalkamat commented on Feb 26, 2024

    @sheetalkamat
    Member

    From documentation:

    This directive marks a file as a default library.

    It can be seen both ways but doc makes it clear the file marked by the directive is default lib file and ignore everything else.

    The impact here is similar to passing noLib on the command line.

    So if you add that directive you would need to include the lib reference directives to files as it is equivalent to noLib

  6. JakeYallop commented on Feb 26, 2024

    @JakeYallop
    Author

    the file marked by the directive is default lib file

    no-default-lib affects the entire compilation, not just the specific file its in, as shown with the original reported issue.

    But I see what you are saying - when using the triple slash to include the types:

    if you use noLib you will be including your own type definitions for these

    we are basically doing this as mentioned in the docs.

    It still seems weird to me that one way works differently to the other. Including the triple slash for lib="dom" affects the entire compilation just as no-default-lib does.

    It also seems like order does not matter. Both of these:

    /// <reference lib="dom" />
    /// <reference no-default-lib="true" />
    /// <reference no-default-lib="true" />
    /// <reference lib="dom" />

    Have the same behaviour.

  7. fatcerberus commented on Feb 27, 2024

    @fatcerberus

    This directive marks a file as a default library.

    This directive instructs the compiler to not include the default library

    Whether a file is itself a default library vs. whether it should include the default libs feel like orthogonal concerns…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions