Как импортировать тип (из другого файла) в файл `d.ts`, не превращая его в модуль?

#typescript #import #namespaces #typescript-typings

#typescript #импорт #пространства имен #typescript-typings

Вопрос:

Просто столкнулся со странной ситуацией, касающейся d.ts файлов и пространств имен.

У меня есть несколько d.ts файлов, в которых я объявляю и объединяю namespace именованные PROJECT .

Смотрите ниже, как он объявляется и автоматически объединяется (в нескольких файлах):

file1.d.ts —— file2.d.ts —— file3.d.ts

 declare namespace PROJECT {

  interface SOME_INTERFACE {
    ...
  }

  type SOME_TYPE = SOME_UNION_TYPE

  // ETC
}
  

Это PROJECT пространство имен автоматически доступно из каждого файла моего проекта. Пример:

SomeComponent.tsx

 const someVariable: PROJECT.SOME_INTERFACE = { 
  // ... 
};
  

Это все ожидаемое поведение.

Моя проблема началась, когда я решил объявить другое пространство имен.

ADMIN_BLOGPOST.d.ts

 import type { ACTION_THUNK_GENERIC } from "@hooks/useReducerThunk";

declare namespace ADMIN_BLOGPOST {
  // HERE I DECLARE MULTIPLE TYPES
  // AND ONE OF THE TYPES USES THE `ACTION_THUNK_GENERIC` TYPE, WHICH IS BEING IMPORTED HERE

  type ACTION_THUNK = ACTION_THUNK_GENERIC<ACTION,GET_STATE>
}
  

И только из-за этого верхнего уровня import type ACTION_THUNK_GENERIC , теперь мое пространство имен больше не доступно автоматически.

VSCode начал рассматривать ADMIN_BLOGPOST.d.ts как модуль и начал заставлять меня обращаться к import этому пространству имен перед его использованием, например:

SomeComponent.tsx

 import type { ADMIN_BLOGPOST } from "@src/types/ADMIN_BLOGPOST";

const someVariable: ADMIN_BLOGPOST.ACTION_THUNK
  

Обратите внимание, что если я удалю этот импорт верхнего уровня (тот, который импортирует ACTION_THUNK_GENERIC ) из ADMIN_BLOGPOST.d.ts файла, то мое ADMIN_BLOGPOST пространство имен станет доступным без необходимости import его предварительного.

Но мне действительно нужен этот импорт. Потому что мне нужен ACTION_THUNK_GENERIC тип, чтобы я мог создать не универсальный ACTION_THUNK тип.

Есть ли другой способ сделать это, чтобы мое ADMIN_BLOGPOST пространство имен было доступно без необходимости импортировать его перед использованием? Т.е. Как import внутри d.ts файла, не превращая его в модуль?

Ответ №1:

Используйте declare global для работы в глобальном пространстве имен независимо от импорта модуля. Например:

 import type { ACTION_THUNK_GENERIC } from "@hooks/useReducerThunk";
declare global {
  declare namespace ADMIN_BLOGPOST {
    type ACTION_THUNK = ACTION_THUNK_GENERIC<ACTION,GET_STATE>
  }
}
  

В качестве альтернативы вы можете использовать динамический импорт:

 declare namespace ADMIN_BLOGPOST {
  type ACTION_THUNK = import("@hooks/useReducerThunk").ACTION_THUNK_GENERIC<ACTION,GET_STATE>
}
  

Комментарии:

1. Спасибо! Не знал этого. Но только что нашел другое решение, которое вы можете добавить к ответу, чтобы сделать его более полным. Синтаксис «динамического» импорта, как в: type ACTION_THUNK = import("@hooks/useReducerThunk").ACTION_THUNK_GENERIC<ACTION,GET_STATE> . Это альтернатива использованию declare global .

2. Спасибо. Добавлено 🌹

3. ASYNC_THUNK_GENERIC Предполагается ACTION_THUNK_GENERIC , что это так?

4. @EdStaub да! Я исправил идентификатор. Спасибо.