You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在校验后将TypeScript可选属性标记为必填

解决TypeScript中登录状态下Token存在性的类型标注问题

问题核心在于:你当前的isLoggedInOrPhoneNumberVerified函数仅返回状态字符串,但TypeScript无法将该状态与data的类型关联起来,因此即便判断状态为"logged in",TS仍认为access_token可能为undefined。

最优解决方案:拆分响应类型+类型守卫函数

通过定义明确的响应类型,并使用**类型谓词(Type Predicate)**让TypeScript能根据判断结果缩小data的类型范围,实现类型安全的分支处理。

  1. 重新定义响应类型
    将原有的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;
  1. 编写类型守卫函数
    用类型谓词函数替代原有的状态判断函数,让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;
}
  1. 类型安全的分支处理
    现在在判断分支中,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:30:41