Accept generics in hook
yuritoledo opened this issue · 8 comments
Hey!
Actually I am using const list = useList()
function useListContext() {
const [data, setData] = useState([])
// ommited
return {
data,
feedData,
}
}
export const [
ListProvider,
useList, // I want to pass the generics to this hook, to use in setData state
] = constate(useListContext)
There are any support like these in your roadmap?
Thanks
I don't understand what you mean. Could you elaborate?
Sure, is something like this:
// page_component.ts
type TOrders = {
foo: string,
bar: boolean
}
const list = useList<TOrders[]>()
typeof list.data === TOrders[]
// hook_component.ts
function useListContext<T>() {
const [data, setData] = useState(T[])
// ommited
return {
data,
feedData,
}
}
export const [
ListProvider,
useList,
] = constate(useListContext)
Today, constate doesn't accept this.
Is it better now?
Got it! Thanks!
I don't know if that's possible. But if you know how to implement that, I would accept a PR.
Right now, the only solution I can think of is casting the function in your app:
const [ListProvider, _useList] = constate(useListContext);
export const useList = _useList as <T>() => T[];
Great, I will check how this cast implementation works here.
And I will try to find some way to open a PR, i really like this lib.
Thank you for your attention!
Is this possible by change these:
function createUseContext(context: React.Context<any>): any {
return () => {
const value = React.useContext(context);
if (isDev && value === NO_PROVIDER) {
// eslint-disable-next-line no-console
console.warn("[constate] Component not wrapped within a Provider.");
}
return value;
};
}
// ...
function constate<P, V, S extends Array<SplitValueFunction<V>>>(
useValue: (props: P) => V,
...splitValues: S
): ContextHookReturn<P, V, S> {
const Context = React.createContext(NO_PROVIDER as V);
// ...
const useContext: any = () => {
if (isDev) {
// eslint-disable-next-line no-console
console.warn(
"[constate] Using the return value of constate as a hook is deprecated. " +
"Please, use the tuple format instead. " +
"See instructions on https://github.com/diegohaz/constate/pull/101"
);
}
return createUseContext(Context)();
};
// ...
}
to:
function createUseContext(context: React.Context<T>): T {
return () => {
const value = React.useContext(context);
if (isDev && value === NO_PROVIDER) {
// eslint-disable-next-line no-console
console.warn("[constate] Component not wrapped within a Provider.");
}
return value;
};
}
// ...
function constate<P, V, S extends Array<SplitValueFunction<V>>>(
useValue: (props: P) => V,
...splitValues: S
): ContextHookReturn<P, V, S> {
const Context = React.createContext(NO_PROVIDER as V); // as React.Context<V>
// ...
const useContext: V = () => {
if (isDev) {
// eslint-disable-next-line no-console
console.warn(
"[constate] Using the return value of constate as a hook is deprecated. " +
"Please, use the tuple format instead. " +
"See instructions on https://github.com/diegohaz/constate/pull/101"
);
}
return createUseContext(Context)();
};
// ...
}
I am sorry that I am unable to create a real patch right now.
Additionally, it would be great to pass generics to the Provider (current types don't like it). Here's a trivial codesandbox showing the issue.
import constate from "constate";
type UseGenericProps<G> = {
custom: G;
};
export function useGenericExample<Generic extends string>({
custom
}: UseGenericProps<Generic>) {
return custom;
}
export const [GenericProvider, useGeneric] = constate(
// TS Error 1
useGenericExample
);
function Consumer() {
// type is `unknown`
const value = useGeneric();
return <>{value}</>;
}
export default function App() {
return (
<GenericProvider<
// TS error 2
"type-argument"
> custom="type-argument">
<Consumer />
</GenericProvider>
);
}
TS Error 1;
function useGenericExample<Generic extends string>({ custom }: UseGenericProps<Generic>): Generic
Argument of type '<Generic extends string>({ custom }: UseGenericProps<Generic>) => Generic' is not assignable to parameter of type '(props: unknown) => string'.
Types of parameters '__0' and 'props' are incompatible.
Type 'unknown' is not assignable to type 'UseGenericProps<string>'. ts(2345)
TS Error 2;
Expected 0 type arguments, but got 1.ts(2558)
It would be great if this were supported
Also would love if this was supported.