Hello Stack社区,
假设我定义了以下字符串文字:
type FormConstants = 'new' | 'edit';
现在我要检查值val
是否等于FormConstants
定义的值:
function inSet(val: string): boolean {
if ((val as FormConstants) === XXX ) {
return true;
} else {
return false;
}
}
而XXX
是我要查找的语句。解决方案为:
keyof FormConstants
in FormConstants
typeof FormConstants
惨败,因为它们每个都使用FormConstants
作为值,而FormConstants
代表一种类型。
编辑:
而且我想避免肯定地使用汇总的switch
/ if-elseif-else
来发布肯定声明
答案 0 :(得分:2)
类型在运行时不存在,因此来自它们的任何信息只能指导编译时检查,而不能指导运行时行为。您可以选择以下几种方法之一:
使用字符串枚举,它是一种类型,也是一个运行时对象:
enum FormConstants { new = 'new', edit = 'edit' }
function inSet(val: string): boolean {
if (Object.values(FormConstants).includes(val)) {
return true;
} else {
return false;
}
}
或者使用字符串文字数组构造一个值数组,并派生出FormConstants
的形式,
function stringLilteralArray<T extends string>(values: T[]) : T[] {
return values
}
const FormConstants = stringLilteralArray(['new', 'edit']) ;
type FormConstants = typeof FormConstants[number];
function inSet(val: string): boolean {
if (FormConstants.includes(val as FormConstants)) {
return true;
} else {
return false;
}
}
如果字符串文字的并集不受您控制,则可以构造一个函数来构建所有值的数组,以确保您传递的值必须与联合中的值完全相同(编译器将强制执行此操作)。因此,即使您必须重复这些值,它们也不会出现差异:
type FormConstants = 'new' | 'edit';
function unionValues<T extends string>(values: { [P in T]: P}) : T[] {
return Object.values(values);
}
const FormConstants = unionValues<FormConstants>({ new : 'new', edit :'edit' }) ;
function inSet(val: string): boolean {
if (FormConstants.includes(val as FormConstants)) {
return true;
} else {
return false;
}
}
修改
上述方法的一种变体,不用数组,使用对象键,肯定会更快:
type FormConstants = 'new' | 'edit';
function unionValues<T extends string>(values: { [P in T]: true }) : typeof values {
return values;
}
const FormConstants = unionValues<FormConstants>({ new : true, edit :true }) ;
function inSet(val: string): boolean {
if (val in FormConstants) {
return true;
} else {
return false;
}
}