typescript - 检查字符串是否是联合类型的成员
为了避免类型转换,我想了解在何种情况下可以安全地确定给定值的类型。我可以像这样使用字符串枚举来做到这一点:
enum Category {
circle = "circle",
square = "square",
}
const isObjValue = (val: any, obj: any) => Object.values(obj).includes(val)
isObjValue('circle', Category) // true
但我该如何用字符串联合来做呢?
const Category = "circle" | "square"
const isValidCategory = (string) => {
if (/* string is in Category */) {
return string as Category
}
}
仍在学习TS!
答案#1
如果你有一个动态值,你可以创建一个用户定义的类型保护,以缩小该值的类型。
type Category = "circle" | "square"
// User-defined type guard that narrows the s from string type
// to Category type if s is either "circle" or "square".
function isCategory(s: string): s is Category {
return s === "circle" || s === "square"
}
const a: string = "some dynamic string"
if (isCategory(a)) {
// a type here is Category
console.log(a, "is Category")
} else {
// a type here is string
console.log(a, "is not Category")
}
答案#2
为了避免必须记住总是更新类型和“is”检查函数,你可以改用数组,让 TS 将其转换为联合类型:
const ALL_CATEGORIES = ["circle", "square"] as const;
type typedCategoryList = typeof ALL_CATEGORIES;
type Category = typedCategoryList[number]; // this compiles to 'circle' | 'square'
const isCategory = (value: string) : value is Category => {
return ALL_CATEGORIES.includes(value as Category )
}
