Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import type cannot be used on classes? #36040

Closed
Tyriar opened this issue Jan 6, 2020 · 7 comments · Fixed by #36092
Closed

import type cannot be used on classes? #36040

Tyriar opened this issue Jan 6, 2020 · 7 comments · Fixed by #36092
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@Tyriar
Copy link
Member

Tyriar commented Jan 6, 2020

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

@DanielRosenwasser
Copy link
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.

@Tyriar
Copy link
Member Author

Tyriar commented Jan 6, 2020

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)?

@DanielRosenwasser
Copy link
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;

@Tyriar
Copy link
Member Author

Tyriar commented Jan 7, 2020

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;

@Tyriar
Copy link
Member Author

Tyriar commented Jan 7, 2020

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

@Tyriar
Copy link
Member Author

Tyriar commented Jan 7, 2020

See microsoft/vscode#88222 for that approach

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Jan 7, 2020
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.8.1 milestone Jan 7, 2020
@RyanCavanaugh
Copy link
Member

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants