Экспортируемая переменная X имеет или использует имя Y из внешнего модуля Z, но не может быть названа

В этом случае я получаю следующую ошибку, используя TS 3.9 с { compilerOptions: {declaration: true }} в моем 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)

В комментарии по связанной проблеме, предложенное в то время, в два обходных пути:

  1. явно импортировать тип
  2. явно объявить тип экспорта (где возникает ошибка)

(1) в этом случае не работает. Я попытался экспортировать все из «a» и импортировать все в «b», и в сообщении об ошибке не было никакой разницы.

Единственное, что сработало, - это очень подробная и сложная для поддержки явная аннотация типа:

// 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;

У меня вопрос:

  • какой обходной путь я могу использовать, который не требует повторения формы объекта?
  • почему импорт типа не решает проблему?

Этот вопрос похож, но отличается от следующего:


person Max Heiber    schedule 23.06.2020    source источник
comment
Удалось ли в итоге придумать что-нибудь более элегантное?   -  person Guy    schedule 27.10.2020
comment
Я повторил форму для мелких вещей и сделал что-то вроде stackoverflow.com/a/64566943/2482570 для длинных вещей iirc. Я поменялся ролями и, к сожалению, не знаю, нашли ли мои коллеги что-то получше или выяснили, почему этот уголок языка внезапно стал педантичным.   -  person Max Heiber    schedule 29.10.2020


Ответы (3)


Это не так уж и красиво, но это минимально инвазивное изменение, которое, похоже, работает в песочнице:

const theExport = {
  A: A as {[K in keyof typeof A]: typeof A[K]},
  B: 2,
  C: 3
};
person lazytype    schedule 28.10.2020
comment
Мне это нравится! не требует обслуживания - person DoronG; 02.11.2020

на основе этого комментария, похоже, что одним из решений может быть:

// 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

См. песочницу.

person DoronG    schedule 28.10.2020

Явно установить тип obj

// 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
person Medet Tleukabiluly    schedule 02.11.2020