Rem.co
Rem.co

Reputation: 3821

Import inside an object

I'm new at TypeScript and am trying to convert my current JavaScript to TypeScript.

In JS I have constructions like:

var roles = {
    x: require('role.x'),
    y: require('role.y')
};

With the purpose of later iterating over those roles like this:

for (var index in roles) {
  var role = new roles[index];
  if (someObject.role == role.role) {
    role.run(someObject);
  }
}

In TypeScript however, It seems I'm not able to do this:

let roles = {
  x: import X from "./roles/x"
}

Which yields

Error:(11, 14) TS1109: Expression expected.
Error:(11, 21) TS1005: ':' expected.
Error:(11, 31) TS1005: ',' expected.
Error:(11, 36) TS1005: ':' expected.

So what would be the TypeScript equivalent of achieving the same -or- an alternate method that's cleaner/the TypeScript way?

Upvotes: 3

Views: 10179

Answers (3)

Amey Parundekar
Amey Parundekar

Reputation: 421

For completeness' sake, now (and since 2017), another way to do this is by using a dynamic import statement.

The V8 Specs give more information on this.

The import() statement returns a promise.

So, in theory, this should work (and look more similar to JS require code):


let roles = {
    x: await import('./roles/x'),
    y: await import('./roles/y')
};

If you want to assign a particular function/entity from the imported file, you should be able to it thus so:


let roles = {
    x: await (async () => {let {X} = await import('./roles/x'); return X;})()
    y: await (async () => {let {Y} = await import('./roles/x'); return Y;})()
};

If one is a fan of using .then() instead (for concurrency), then this StackOverflow answer shows replacement of await by .then() to assign the returned promise to an object key.

I hope this helps.

Upvotes: 7

Paleo
Paleo

Reputation: 23702

It's not about TypeScript but ES6. Imports are static, they cannot be used dynamically:

import * as x from "./roles/x";
import * as y from "./roles/y";
let roles = {
    x: x,
    y: y
};

See a good introduction to ES6 modules here. In the section "Static vs. dynamic":

For a dynamic language, JavaScript has gotten itself a surprisingly static module system.

  • All flavors of import and export are allowed only at toplevel in a module. There are no conditional imports or exports, and you can’t use import in function scope.

  • All exported identifiers must be explicitly exported by name in the source code. You can’t programmatically loop through an array and export a bunch of names in a data-driven way.

Upvotes: 3

AlexG
AlexG

Reputation: 4045

ES6 imports must be found at the top level of your module, else it's a syntax error.

import * as x from "./roles/x";
import * as y from "./roles/y";

let roles = {x, y};

Upvotes: 4

Related Questions