I am working inside a TypeScript app that uses an NPM package that is implemented in plain JavaScript. In order to provide myself with some type safety, I am creating my own TypeScript ambient module to provide types for this library.
One of the components that is exported from this library is a React context component that should accept a generic type. This app is unfortunately not upgraded to use hooks so I'm limited to the context components. Here is an example of what I am trying to type:
import { URLStateContext } from 'some-library'
<URLStateContext.Consumer>
{({ params }) => <div />}
</URLStateContext.Consumer>
I've declared an ambient module as such:
declare module 'some-library' {
// ...
}
What I'd like to be able to do is type the URLStateContext component in my ambient module to accept a generic. In the above example, this generic type should apply to the params value in the consumer.
I've tried a mix of things, each with their own pros and cons, but none that I can figure out how to fully type properly.
1)
import { Context } from 'react'
declare module 'some-library' {
export type URLStateContext<TUrlState> = Context<{ params: TUrlState }>
}
My first thought was to try the above since the return type of createContext is Context<...>. This however give me an error that states "URLStateContext only refers to a type, but is being used as a value here."
2)
import { Context } from 'react'
declare module 'some-library' {
export const URLStateContext: Context<any>
}
This actually compiles, but here I lose the generic, which means that I either need to live with the any, or I need to try and type the child function on the consumer:
<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>
Any help would be appreciated!