gpt4 book ai didi

typescript - 获取字符串枚举值的类型

转载 作者:行者123 更新时间:2023-12-04 02:59:12 24 4
gpt4 key购买 nike

我有一个字符串枚举,如下所示:

export enum FMEvents {
RECORD_ADDED = "@firemodel/RECORD_ADDED",
RECORD_CHANGED = "@firemodel/RECORD_CHANGED",
RECORD_MOVED = "@firemodel/RECORD_MOVED",
RECORD_REMOVED = "@firemodel/RECORD_REMOVED",
}

我希望能够将函数的输入限制为枚举的字符串值(例如,“@firemodel/RECORD_ADDED”等)。

我想我也许可以对方法签名执行以下操作:
public doSomething(event: keyof FMEvents) { ... }

但是为此的输入都是错误的(我认为它给了我枚举对象的键,不确定但肯定是错误的)。

然后我尝试了:
public doSomething(event: FMEvents) { ... }

这让我可以调用 doSomething()FMEvents.RECORD_CHANGED但它不允许我用 doSomething("@firemodel/RECORD_CHANGED") 的已解析键调用它.

我正在寻找一种将其限制为定义为枚举中值的字符串的方法,仅此而已。有了这个,我希望上面的两种调用方法都能通过类型检查。

最佳答案

TypeScript 4.1 引入 template literal types其中,除其他外,它将枚举转换为其字符串表示形式。因此,您的目标可以简单地实现为:

function doSomething(event: `${FMEvents}`) { }

doSomething("@firemodel/RECORD_CHANGED"); // okay
doSomething(FMEvents.RECORD_MOVED); // still okay
Playground link to code

前 TS4.1 答案:
TypeScript 并不容易将枚举值类型扩展到它们派生的字符串或数字文字。 (有一个 complication that prevents using intersections to help with this )您可以使用 conditional types 获得相当接近的结果。 :
type Extractable<T, U> = T extends U ? any : never
type NotString<T> = string extends T ? never : any
function promoteStringToFMEvents<K
extends string & NotString<K> & Extractable<FMEvents, K>>(
k: K
): Extract<FMEvents, K> {
return k;
}

const fmAdded = promoteStringToFMEvents("@firemodel/RECORD_ADDED"); // FMEvents.RECORD_ADDED
const fmOops = promoteStringToFMEvents("@firemodel/RECORD_ADDLED"); // error
在上面的代码中, Extractable<T, U>返回 any如果 T或其任何成分可分配给 U , 和 never除此以外。和 NotString<T>返回 anyT不是 string或更宽,以及 never除此以外。通过约束 KpromoteStringToFMEvents()string & NotString<K> & Extractable<FMEvents, K> ,我们说类型参数 K必须是 FMEvents 的某个元素(或元素的并集)的某个字符串文字(或字符串文字的联合)可以分配给。
所以函数 promoteStringToFMEvents()将接受您期望的字符串文字(或字符串文字的联合)。该函数也只返回 FMEvents 的关联元素通过将输入值分配给 Extract<FMEvents, K> , 它只取出 FMEvents 的那些片段匹配 K .
所以你可以写你的 doSomething()方法,使其在 K 类型中是通用的上面,并且在方法的实现中,您可以(如果需要)通过将字符串分配给类型为 Extract<FMEvents, K> 的变量来将字符串提升为枚举。 .
使用 doSomething() 的显式实现进行编辑:
class Blomp {
public doSomething<K
extends string & NotString<K> & Extractable<FMEvents, K>>(k: K) {
// k is of some subtype of "@firemodel/RECORD_ADDED" |
// "@firemodel/RECORD_CHANGED" | "@firemodel/RECORD_MOVED" |
// "@firemodel/RECORD_REMOVED"

// if you need to interpret k as a subtype of FMEvents, you can:
const kAsFMEvent: Extract<FMEvents, K> = k;

// or even wider as just FMEvents
const fmEvent: FMEvents = kAsFMEvent;

// do what you want here
}
}
希望有帮助。祝你好运!

关于typescript - 获取字符串枚举值的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50884025/

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