Max Heiber
Max Heiber

Reputation: 15572

Exported variable X has or is using name Y from external module Z but cannot be named

I get the following error in this case using TS 3.9 with { compilerOptions: {declaration: true }} in my tsconfig.json:

// a.ts
export const key = 1234
export const obj = {
    [key]: 1
};
export default obj;

// b.ts
import A from "./a";
import { key} from "./a"

// Exported variable 'theExport' has or is using name 'key' from external module "c:/tsexample/src/a" but cannot be named.ts(4023)
const theExport  = {
  A: A,
  B: 2,
  C: 3,
};
export default theExport
// Exported variable 'theExport' has or is using name 'key' from external module "c:/tsexample/src/a" but cannot be named.ts(4023)

In a comment on a related issue the PM of TS at the time suggested two workarounds:

  1. explicitly import the type
  2. explicitly declare the type of the export (where the error occurs)

(1) does not work in this case. I tried exporting everything from 'a' and importing everything in 'b' and there was no difference to the error message.

The only thing that worked was this very verbose and hard to maintain explicit type annotation:

// updated b.ts
import A from "./a";

const theExport: {
    // https://github.com/microsoft/TypeScript/issues/9944
  [index: string]: typeof A | number;
} = {
  A: A,
  B: 2,
  C: 3,
};
export default theExport;

My question is:

This question is similar but distinct from:

Upvotes: 9

Views: 9734

Answers (3)

Medet Tleukabiluly
Medet Tleukabiluly

Reputation: 11950

Explicitly set obj type

// a.ts
export const key = 1234
export const obj = {
  [key as number]: 1
}
export default obj

// b.ts
import A from './a'

const theExport = {
  A: A,
  B: 2,
  C: 3
}
export default theExport

Upvotes: 0

lazytype
lazytype

Reputation: 925

It's not that pretty, but this is a minimally invasive change that seems to work in a sandbox:

const theExport = {
  A: A as {[K in keyof typeof A]: typeof A[K]},
  B: 2,
  C: 3
};

Upvotes: 5

DoronG
DoronG

Reputation: 2663

based on this comment, looks like one solution could be:

// a.ts
export const key = 1234
export const obj = {
    [key]: 1
};
export default obj;

// b.ts
import A from "./a";

interface ITheExport {
  A: typeof A;
  B: number;
  C: number;
}

const theExport: ITheExport = { // strong typing the object instead of using inference
  A: A,
  B: 2,
  C: 3,
};
export default theExport

See sandbox

Upvotes: 1

Related Questions