如何在校验后将TypeScript可选属性标记为必填
解决TypeScript中登录状态下Token存在性的类型标注问题
问题核心在于:你当前的isLoggedInOrPhoneNumberVerified函数仅返回状态字符串,但TypeScript无法将该状态与data的类型关联起来,因此即便判断状态为"logged in",TS仍认为access_token可能为undefined。
最优解决方案:拆分响应类型+类型守卫函数
通过定义明确的响应类型,并使用**类型谓词(Type Predicate)**让TypeScript能根据判断结果缩小data的类型范围,实现类型安全的分支处理。
- 重新定义响应类型
将原有的MyResponse拆分为两种明确的类型,分别对应不同的接口响应场景:
// 登录成功:必含access_token和refresh_token type LoggedInResponse = { access_token: string; refresh_token: string; }; // 手机号验证成功:无token(用never确保不会出现多余属性) type PhoneVerifiedResponse = { access_token?: never; refresh_token?: never; }; // 联合两种响应类型 type MyResponse = LoggedInResponse | PhoneVerifiedResponse;
- 编写类型守卫函数
用类型谓词函数替代原有的状态判断函数,让TypeScript能识别当前data的具体类型:
// 判断是否为登录成功的响应 function isLoggedIn(data: MyResponse): data is LoggedInResponse { return 'access_token' in data && typeof data.access_token === 'string'; } // 判断是否为手机号验证成功的响应 function isPhoneNumberVerified(data: MyResponse): data is PhoneVerifiedResponse { return data.access_token === undefined && data.refresh_token === undefined; }
- 类型安全的分支处理
现在在判断分支中,TypeScript会自动识别data的类型,不会再报错:
const data: MyResponse = { access_token: 'abc', refresh_token: 'cba' }; const saveToSecureStore = (key: string, token: string) => { // 存储逻辑 return token; }; if (isPhoneNumberVerified(data)) { console.log('phone number verified'); } else if (isLoggedIn(data)) { // TS明确知道此处data是LoggedInResponse,access_token必存在 saveToSecureStore("access_token", data.access_token); }
临时应急方案:非空断言(不推荐)
如果你不想重构类型,也可以在分支中使用非空断言运算符!强制告诉TS该属性不为undefined,但这种方式跳过了TS的类型检查,存在潜在风险,仅建议在你100%确定属性存在时使用:
else if (myStatus === "logged in") { saveToSecureStore("access_token", data["access_token"]!); }
内容的提问来源于stack exchange,提问作者meg hidey
相关产品推荐
相关产品推荐

