I’m a typescript newbie.
Description
I have a typescript react application, and now I’ve had a problem that I need to dynamic watch the values comes out of the watch()
from react-hook-from
based on the different param that passed into my customized hook.
which means from cosumer side
when first param is 'k'
, typescript should be automatcally give suggestion and the type should be interface kq
.
when first one is 'c'
, typescript should be automatcally give suggestion and the type should be interface cq
.
I tried the below solution type pqp<T> = T extends k ? kq : T extends c ? cq : never;
, but it seems union 'kq'
and 'cq'
, no matter what is the first param, it always suggest 's'
and 'ce'
, which exists both in 'kq'
and 'cq'
.
I’ve been also trying a lot of solution on the internet, but it seems not working…post here ask for help.
Hook Code Block
import { useMemo } from 'react';
import { useForm } from 'react-hook-form'
type k = 'k';
type c = 'c';
type p = k | c;
interface kq {
s: string;
t: string;
ce: string;
}
interface cq {
s: string;
c: string;
ce: string;
}
type pqp<T> = T extends k ? kq : T extends c ? cq : never;
const useMyHook = <T extends p>(product: T, qp?: pqp<T>) => {
const generatedQP = useMemo(() => {
if (product === 'c') {
return ({
will_return_s: qp?.s || '',
will_return_ce: qp?.ce || 'default',
will_return_c: qp?.c || '' // ERROR! property c does not exist on kq or cq. property c doesn not exist on kq
});
} else {
return ({
will_return_s: qp?.s || '',
will_return_ce: qp?.ce || 'default',
will_return_c: qp?.t || '' // ERROR! property t does not exist on kq or cq. property t doesn not exist on cq
});
}
}, [product]);
const methods = useForm({
criterialMode: 'all',
defaultValues: generatedQP
})
return methods;
}
Consumer Code Block
function component() {
const p: p = 'c';
const { watch } = useMyHook(p)
const {/** these will change and report error based on what p is */} = watch();
// I also noticed that the type is always 'kq' for watch();
}
2
Answers
You can use an
enum
to store the values.You can use a type guard to narrow type of
qp
when you use it: