typescript - 如何检查给定值是否在联合类型数组中
问题描述
我有一个给定联合类型的数组,然后想检查来自联合类型超集的字符串是否包含在数组中(运行时检查):
const validOptions: ("foo" | "bar")[] = ["foo", "bar"]
type IArrType = typeof validOptions[number]
const key: IArrType | "alien" = "alien" // Rather: some random function
const isKeyInArr = validOptions.indexOf(key) > -1 // Error: "alien" is not assignable to "foo" | "bar"
// Fix 1:
const isKeyValidCast = validOptions.indexOf(<IArrType>key) > -1
// Fix 2:
const isKeyValidExplicit =
key === "alien" ? false : validOptions.indexOf(key) > -1 // OK: type guard magic
修复 1 可以,但不是很优雅。Fix 2 欺骗了编译器,但运行时具有误导性和低效。在我的情况下,“外星人”字符串类型只是任何不在联合类型中的字符串的占位符。
有没有什么方法可以在没有强制转换或显式测试的情况下编译?可以否定表达式,以便我们让这个“类型保护”工作吗?
顺便说一句:这个非常酷的答案展示了如何从值列表构造类型化元组:Typescript 从元组/数组值中派生联合类型
解决方案
The accepted answer uses type assertions/casting but from the comments it appears the OP went with a solution using find
that works differently. I prefer that solution also, so here's how that can work:
const configKeys = ['foo', 'bar'] as const;
type ConfigKey = typeof configKeys[number]; // "foo" | "bar"
// Return a typed ConfigKey from a string read at runtime (or throw if invalid).
function getTypedConfigKey(maybeConfigKey: string): ConfigKey {
const configKey = configKeys.find((validKey) => validKey === maybeConfigKey);
if (configKey) {
return configKey;
}
throw new Error(`String "${maybeConfigKey}" is not a valid config key.`);
}
Note that this can guarantee that a string is a valid ConfigKey
both at runtime and compile time.
推荐阅读
- azure-active-directory - 迁移到 .net5 后的 Blazor webassembly azure 广告身份验证问题
- postgresql - 如何在 dbeaver 中为 Postgresql 配置主客户端
- python - 在花园 Python 练习中放置 gnome
- javascript - 将用户点击推送到数组,然后在 Javascript 中设置时间后显示数组?
- python - 如何让我的鼠标左键在 tkinter、python 的棋盘井字游戏中画一个圆圈
- flutter - 在 Flutter 中制作唯一 ID 列表平铺
- javascript - ReferenceError: con 未定义
- excel - Excel VBA:将图片移动到另一张纸而不复制/粘贴
- java - 如何在 Java/Kotlin 中覆盖另一个类实例的方法?
- azure - 在 Python 中使用 Azure Face Api,如果在视频流中检测到同一个人,如何返回单个 faceId 或一组 FaceId?