Как экспортировать компонент контекста React, который берет общий код из окружающего модуля в TypeScript?

#reactjs #typescript #react-context

Вопрос:

Я работаю в приложении TypeScript, которое использует пакет NPM, реализованный на обычном JavaScript. Чтобы обеспечить себе некоторую безопасность типов, я создаю свой собственный окружающий модуль TypeScript для предоставления типов для этой библиотеки.

Одним из компонентов, экспортируемых из этой библиотеки, является компонент контекста React, который должен принимать универсальный тип. Это приложение, к сожалению, не обновлено для использования крючков, поэтому я ограничиваюсь контекстными компонентами. Вот пример того, что я пытаюсь ввести:

 import { URLStateContext } from 'some-library'

<URLStateContext.Consumer>
  {({ params }) => <div />}
</URLStateContext.Consumer>
 

Я объявил окружающий модуль как таковой:

 declare module 'some-library' {
  // ...
}
 

То, что я хотел бы иметь возможность сделать, — это ввести URLStateContext компонент в мой окружающий модуль, чтобы он принимал универсальный. В приведенном выше примере этот универсальный тип должен применяться к params значению в потребителе.

Я пробовал разные вещи, каждая со своими плюсами и минусами, но ни одна из них не позволяет мне понять, как правильно печатать.

1)

 import { Context } from 'react'

declare module 'some-library' {
  export type URLStateContext<TUrlState> = Context<{ params: TUrlState }>
}
 

Моей первой мыслью было попробовать вышеописанное, так как возвращаемый тип createContext is Context<...> . Однако это приводит меня к ошибке, в которой говорится: « NerdletStateContext относится только к типу, но используется здесь в качестве значения».

2)

 import { Context } from 'react'

declare module 'some-library' {
  export const URLStateContext: Context<any>
}
 

Это на самом деле компилируется, но здесь я теряю универсальность, а это значит , что мне нужно либо смириться с any этим, либо попытаться ввести дочернюю функцию на потребителе:

 <URLStateContext.Consumer>
  {({ params }: { params: MyParams }) => <div />}
</URLStateContext.Consumer>
 

I’d like to be able to pass a generic to the component itself so that its callback function is typed for me correctly. Here is my ideal code:

 interface Params {
  // ...
}

// `params` would automatically be typed correctly
<URLStateContext.Consumer<Params>>
  {({ params }) => <div />}
</URLStateContext.Consumer>
 

Любая помощь будет признательна!