question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow constant strings as string literals for dynamic import statements.

See original GitHub issue

Search Terms

Use constant string in place of string literal for dynamic import statements.

Suggestion

Honestly I don’t know if this is a bug or a suggestion.

Is there a way to allow constant string to represent string literals? I’m thinking this should work, but it doesn’t. For example:

const moduleName = "../../../Project/src/Mod";

async function doSomething() {
    var mod = await import(moduleName); // (works only if a string literal at the moment)
}

In the case above, “mod” is of type “any” because the compiler doesn’t recognize the string literal in the constant moduleName (for literal strings, the types are correctly pulled). I’m not sure if this was an oversight, but it makes sense to allow it, since constant strings cannot be reassigned. The only workaround is to wrap await import("../../../Project/src/Mod"); in a function:

async function getMod() { return import("../../../Project/src/Mod"); }
async function doSomething() {
    var mod = await getMod(); // (method required since const strings cannot be used to import module type)
}    

I may also add, it seems very difficult to import namespaces using dynamic imports, which I think is another terrible oversight.

async function doSomething() {
    var mod = await import("../../../Project/src/Mod"); // (forced to use a string literal to get typings)
    var o: mod.SomeClass; // ERROR, cannot find namespace 'mod'
    // var o: InstanceType<typeof mod.SomeClass>; // workaround1
    // var o: import("../../../Project/src/Mod").SomeClass; // workaround2 (who wants to keep typing full paths? A const string would be nice here.)
}

That doesn’t even make sense. A namespace, while a type, is still a reference under the hood, and thus should still be importable dynamically somehow; perhaps like:

async function doSomething() {
    import mod = await import("../../../Project/src/Mod"); // (forced to use a string literal to get typings)
    var o: mod.SomeClass;
}

I think all this would aim to better support dynamic imports “on demand” instead of modules forcibly loading every single module when some may not be needed at all, It could also help promote faster initial page loads in many cases. 😉

Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:10
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
rbucktoncommented, Jul 15, 2019

Wouldn’t this possibly involve needing to parse and rebind during check if the imported file wasn’t previously part of the compilation? I could only see this work for files already included in the program.

0reactions
ShanonJacksoncommented, Dec 24, 2019

Just to throw my use case in as well as i’d actually really like generics in import types. I.E type importOf<T extends string> = typeof import(T); This will allow incredible new possibilities for my isomorphic projects because i’ll be able to do this…

const fetchUsers = api("./api/get-name")

const api<T extends string>(url: string): Promise<ReturnType<typeof import(T)["default"]>> => {
      return fetch(url.replace(".", "")
}

Where all my API endpoints export a default endpoint and which returns some data. If anyone uses NextJS with typescript they’ll know this would be an insanely useful feature because NextJS enforces file-path routing therefore all endpoints export a default and are from the same file as the url path.

Read more comments on GitHub >

github_iconTop Results From Across the Web

String literal expected. when importing in typescript
It give me the error: [ts] String literal expected. Can I not interpolate strings when importing? typescript.
Read more >
Understanding Template Literals in JavaScript - DigitalOcean
With template literals, an expression can be embedded in a placeholder. A placeholder is represented by ${} , with anything within the curly ......
Read more >
import - JavaScript - MDN Web Docs - Mozilla
import declarations are designed to be syntactically rigid (for example, only string literal specifiers, only permitted at the top-level, all ...
Read more >
Dynamic imports solve all the problems, right? - Minko Gechev
Statically analyze the path because it's a string literal. Let's suppose for a second that this is a valid syntax: import { foo...
Read more >
Overview | Odin Programming Language
Comments are parsed as tokens within the compiler. This is to allow for future work on automatic documentation tools. String and character literals...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found