Given some enum MyEnum {ONE, TWO}
, I wanted to write a function called like
useMyFun(MyEnum, MyEnum.ONE);
and I failed to type it properly. Now I have something like the following
type StringKeyOf<T> = Extract<keyof T, string>;
type EnumNumber<E> = Record<StringKeyOf<E>, number>;
function useMyFun<E extends EnumNumber<E>, V extends number=number> (
anEnum: E,
initialState: number) : {value: V, setValue: (v: V) => void}
{
const [value, setValue] = useState<V>(initialState as V);
//.... more stuff using both arguments omitted
return {value, setValue};
}
It's a react-hook, but this doesn't matter as all you need to compile it is a dummy
function useState<V>(initialState: V) {
const result: [V, (v: V) => void] = [initialState, v => { }];
return result;
}
It works (using the current typescript version), but it allows me to call useMyFun(MyEnum, -1)
as well, which is wrong. Note that I only care about enums like above, i.e., enums with default numerical values, no specified values and no const
modifier.
*I also need that the return type has value: MyEnum
rather than number
.
I know that the runtime value of MyEnum
is {0: 'ONE', 1: 'TWO', ONE: '0', TWO: '1'}
which means that the above typing is actually wrong. However, this was the only way how to get the first argument compile. The second argument when dealing with MyEnum
should actually be 0 | 1
, but I can't get it working.
I really need both the enum object and the value in the function. Can someone get the types right?