gpt4 book ai didi

typescript - 如何键入带枚举的函数

转载 作者:行者123 更新时间:2023-12-03 17:24:50 25 4
gpt4 key购买 nike

给定一些 enum MyEnum {ONE, TWO} ,我想写一个函数叫做like

useMyFun(MyEnum, MyEnum.ONE);

我没有正确输入。现在我有类似以下的东西
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};
}

这是一个 react 钩子(Hook),但这并不重要,因为你需要编译它是一个虚拟的
function useState<V>(initialState: V) {
const result: [V, (v: V) => void] = [initialState, v => { }];
return result;
}

它可以工作(使用当前的 typescript 版本),但它允许我调用 useMyFun(MyEnum, -1)同样,这是错误的。请注意,我只关心上面的枚举,即具有默认数值、没有指定值和没有 const 的枚举修饰符。

*我还需要返回类型有 value: MyEnum而不是 number .

我知道 MyEnum 的运行时值是 {0: 'ONE', 1: 'TWO', ONE: '0', TWO: '1'}这意味着上面的输入实际上是错误的。然而,这是编译第一个参数的唯一方法。处理 MyEnum 时的第二个参数实际上应该是 0 | 1 ,但我无法让它工作。

我真的需要枚举对象和函数中的值。有人可以正确输入类型吗?

最佳答案

相关问题可以找here
还有另一种方法可以确定初始值是否有效。
如您所知,TS 可能会处理 enum作为 number或作为对象或typeof enum . typescript 以类似的方式处理 classes .
我们需要一些如何获取enum的数字键.
让我们尝试遍历 enum键:

enum MyEnum {
ONE,
TWO
}

type Enumerate<Enum extends number | string> = keyof {
[Prop in Enum]: Prop
}

// non generic version
type Keys = keyof typeof MyEnum
type Enumerate2 = keyof {
[Prop in Keys]: Prop
}


type Result = Enumerate<MyEnum> // MyEnum, not good
它不起作用,因为 TS 足够聪明,可以找出我们正在迭代枚举键。因此我们得到 MyEnum而不是 0 | 1 .
我们可以包装 Prop键入字符串以欺骗 typescript 。
enum MyEnum {
ONE,
TWO
}

type Enumerate<Enum extends number | string> = keyof {
[Prop in `${Enum}`]: Prop
}

type Result = Enumerate<MyEnum> // "0" | "1"
现在好多了。但这仍然不是我们想要的。在当前版本的 typescript 中,无法以通用方式从字符串中提取数字。
但是我们总是可以将字符串与在比较过程中包裹在字符串中的数字进行比较。
我的意思是这样的: "0" extends ${数字} ? ...`
上面的代码是完全有效的。
enum MyEnum {
ONE,
TWO
}

type Enumerate<Enum extends number | string> = keyof {
[Prop in `${Enum}`]: Prop
}

type Result = Enumerate<MyEnum> // "0" | "1"


type Values<T> = T[keyof T]

type IsKeyValid<InitialValue extends number, Enum extends Record<string | number, string | number>> =
`${InitialValue}` extends Enumerate<Values<Enum>> ? InitialValue : never

function useMyFun<
Enum extends Record<string | number, string | number>,
InitialValue extends number,
>(anEnum: Enum, initialState: IsKeyValid<InitialValue, Enum>) { }

useMyFun(MyEnum, MyEnum.ONE) // ok
useMyFun(MyEnum, 0) // ok

useMyFun(MyEnum, -1) // error
useMyFun(MyEnum, NaN) // error
Playground Enum - 是枚举的推断类型 InitialValue - 是第二个参数的推断类型。 IsKeyValid - 是一种实用程序类型,用于检查是否包装成字符串 InitialValue是否等于允许的枚举键。如果相等 - 返回 InitialValue , 否则返回 never附言相关 question使用 React 组件 Prop

关于typescript - 如何键入带枚举的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62268023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com