如何判断字符串是否属于TypeScript的CSSAdditional类型?
TypeScript运行时判断JSON解析值是否属于特定联合类型
问题背景
我定义了以下TypeScript类型来描述控件:
type CSSControl = "Button" | "TextField" | "MultiSelect" | "CheckBox" | "Radio";
其中TextField、Button和MultiSelect支持额外样式,因此定义了对应的联合类型:
type CSSAdditional = "LB_Button" | "HD_TextField" | "MS_MultiSelect";
同时创建了具体的控件类型:
type TextFieldControl = { control: "TextField", style: "HD_TextField", } type MultiSelectControl = { control: "TextField", // 注:此处疑似笔误,建议修正为"MultiSelect" style: "MS_MultiSelect", }
控件信息来自JSON解析,示例JSON如下:
{ "page": { "name": "TextField", "additionalStyles": "true", "productOptions": "MultiSelect" } }
已将JSON解析为对象,但无法判断解析后的字符串(如page.name)是否属于CSSAdditional类型,希望实现如下逻辑:
const page = JSON.parse(pageStr); const fieldControl = page.name; const applyAdditionalStyles = page.additionalStyles; if((fieldControl is a type of CSSAdditional) && applyAdditionalStyles){ // 应用额外样式 }
解决方案
TypeScript类型仅存在于编译阶段,JSON解析后的值是运行时的普通JS值,需结合运行时校验与类型守卫实现需求:
1. 创建运行时枚举数组
先定义包含CSSAdditional所有可能值的数组,作为运行时校验的依据:
const CSSAdditionalValues = ["LB_Button", "HD_TextField", "MS_MultiSelect"] as const;
使用as const让TypeScript推断出数组元素为字面量类型,后续可自动关联到CSSAdditional类型。
2. 定义类型守卫函数
编写类型守卫函数,在运行时检查值的同时,让TypeScript在编译阶段识别该类型:
function isCSSAdditional(value: unknown): value is CSSAdditional { return typeof value === "string" && CSSAdditionalValues.includes(value as CSSAdditional); }
3. 完整使用示例
将类型守卫应用到业务逻辑中:
// 关联类型与运行时数组,确保两者一致 type CSSAdditional = typeof CSSAdditionalValues[number]; const pageStr = `{ "page": { "name": "TextField", "additionalStyles": "true", "productOptions": "MultiSelect" } }`; const page = JSON.parse(pageStr); const fieldControl = page.name; // JSON解析后的"true"是字符串,需转换为布尔值 const applyAdditionalStyles = page.additionalStyles === "true"; if (isCSSAdditional(fieldControl) && applyAdditionalStyles) { // 此处fieldControl会被TypeScript推断为CSSAdditional类型 console.log(`应用额外样式:${fieldControl}`); // 执行样式应用逻辑 }
补充说明
- 注意
MultiSelectControl类型中control字段的笔误,建议修正为"MultiSelect"以保证类型与实际控件匹配。 - JSON解析后的
additionalStyles是字符串"true",需手动转换为布尔值,否则非空字符串会被直接判定为true,导致逻辑错误。
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

