maa*_*nus 5 enums typescript typescript-generics
鉴于一些enum MyEnum {ONE, TWO},我想编写一个名为 like
useMyFun(MyEnum, MyEnum.ONE);
Run Code Online (Sandbox Code Playgroud)
我没有正确输入它。现在我有如下内容
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};
}
Run Code Online (Sandbox Code Playgroud)
这是一个 react-hook,但这并不重要,因为编译它所需的只是一个虚拟对象
function useState<V>(initialState: V) {
const result: [V, (v: V) => void] = [initialState, v => { }];
return result;
}
Run Code Online (Sandbox Code Playgroud)
它可以工作(使用当前的打字稿版本),但它也允许我调用useMyFun(MyEnum, -1),这是错误的。请注意,我只关心上面的枚举,即具有默认数值、没有指定值和const修饰符的枚举。
*我还需要返回类型具有value: MyEnum而不是number.
我知道运行时值MyEnumis{0: 'ONE', 1: 'TWO', ONE: '0', TWO: '1'}这意味着上面的输入实际上是错误的。但是,这是编译第一个参数的唯一方法。处理时的第二个参数MyEnum实际上应该是0 | 1,但我无法让它工作。
我真的需要枚举对象和函数中的值。有人可以得到正确的类型吗?
首先我要说的是,我强烈建议不要这样做,但为了好玩,这里有一个可以实现您正在寻找的行为的技巧。该解决方案有效地将枚举的值变成不透明类型。
enum _MyEnum {
ONE,
TWO,
}
declare const __brand: unique symbol;
type MyEnum = {
[K in keyof typeof _MyEnum]: (typeof _MyEnum)[K] & {
readonly [__brand]: never;
};
};
const MyEnum: MyEnum = _MyEnum as any;
type StringKeyOf<T> = Extract<keyof T, string>;
type EnumNumber<E> = Record<StringKeyOf<E>, number>;
function useMyFun<E extends EnumNumber<E>, V extends E[keyof E]>(
anEnum: E,
initialState: V
): { value: V; setValue: (v: V) => void } {
const [value, setValue] = useState<V>(initialState as V);
//.... more stuff using both arguments omitted
MyEnum.ONE.toFixed;
MyEnum.ONE;
return { value, setValue };
}
useMyFun(MyEnum, MyEnum.ONE);
useMyFun(MyEnum, -1);
Run Code Online (Sandbox Code Playgroud)