Skip to content

import type cannot be used on classes? #36040

Closed

Description

@Tyriar

I was excited when I heard about import type as I've been using dynamic imports on a component to save start up time in vscode for some time, however it's very fragile as I only want to import types and not implementation.

When I try to put the import type guard in place I get the following error though:

image

What's happening here is I'm wanting to import an export class definition and only reference it as a type by getting its constructor with typeof. However I'm getting an error that it's being used as a value inside a : type definition?

Terminal definition: https://github.com/xtermjs/xterm.js/blob/1c06e576aea6b1a63dc71d180ae92cc1c6d68c7c/typings/xterm.d.ts#L385
Above usage: https://github.com/microsoft/vscode/blob/81fb34c445098d43d0f25b4e1868ca421022d4de/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts#L8-L16

Activity

  1. DanielRosenwasser commented on Jan 6, 2020

    @DanielRosenwasser
    Member

    Hm - I suppose the workaround is to use typeof import() types instead, which is pretty reasonable here since all of your imports are distinct anyway so the repetition will be minimal.

    let Terminal: typeof import("xterm").Terminal;
    let WebLinksAddon: typeof import("xterm-addon-web-links").WebLinksAddon;
    let SearchAddon: typeof import("xterm-addon-search").SearchAddon;
    let WebglAddon: typeof import("xterm-addon-webgl").WebglAddon;

    I do think that this is working as intended, but I think it begs the question of whether we need import typeof statements. My hunch says "no" because typeof imports probably come up relatively infrequently, and when they do, there's already a way to do this with typeof import("...").Entity.Name. But I'm willing to change my mind if the demand is there.

  2. Tyriar commented on Jan 6, 2020

    @Tyriar
    ContributorAuthor

    let Terminal: typeof import("xterm").Terminal would not work as Terminal needs to be top level so it can be references throughout the file and if the import is top level then it will be loaded when the file is loaded (not when the function is triggered)?

  3. DanielRosenwasser commented on Jan 6, 2020

    @DanielRosenwasser
    Member

    Ugh, then you'll really have to write the moral equivalent of a typeof import using aliases.

    type XTermTerminal = typeof import("xterm").Terminal;
    type XTermWebLinksAddon = typeof import("xterm-addon-web-links").WebLinksAddon;
    type XTermSearchAddon = typeof import("xterm-addon-search").SearchAddon;
    type XTermWebglAddon = typeof import("xterm-addon-webgl").WebglAddon;
    
    let Terminal: XTermTerminal;
    let WebLinksAddon: XTermWebLinksAddon;
    let SearchAddon: XTermSearchAddon;
    let WebglAddon: XTermWebglAddon;
  4. Tyriar commented on Jan 7, 2020

    @Tyriar
    ContributorAuthor

    This seems to work but I question the usefulness of import type if I can't even use it with my dynamic imports, what other cases would you want to strictly import only types?

    type XTermTerminal = import('xterm').Terminal;
    type XTermTerminalCtor = typeof import('xterm').Terminal;
    type XTermWebLinksAddonCtor = typeof import('xterm-addon-web-links').WebLinksAddon;
    type XTermSearchAddonCtor = typeof import('xterm-addon-search').SearchAddon;
    type XTermWebglAddonCtor = typeof import('xterm-addon-webgl').WebglAddon;
    
    let Terminal: XTermTerminalCtor;
    let WebLinksAddon: XTermWebLinksAddonCtor;
    let SearchAddon: XTermSearchAddonCtor;
    let WebglAddon: XTermWebglAddonCtor;
  5. Tyriar commented on Jan 7, 2020

    @Tyriar
    ContributorAuthor

    Is there some easier way to use an interface as a class? It seems ugly to have to spell out the constructor interface?

  6. Tyriar commented on Jan 7, 2020

    @Tyriar
    ContributorAuthor

    See microsoft/vscode#88222 for that approach

  7. RyanCavanaugh commented on Jan 7, 2020

    @RyanCavanaugh
    Member

    Andrew Branch (@andrewbranch) per our Teams discussion it sounds like we landed on allowing typeof T (in type positions) to operate on Ts imported through type-only imports as long as they also have a value meaning

  8. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions