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

TypeScript联合类型属性访问报错 求符合最佳实践的解决方案

解决TypeScript联合类型属性访问报错的最佳实践

你的问题核心是:greetObject和errorObject组成的联合类型没有共同标识属性,TypeScript无法在编译期确定当前值的具体类型,因此直接访问text或errorText会触发类型错误。你提到的any和字符串索引签名确实会弱化TypeScript的类型优势,这里提供两种符合TypeScript设计理念的解决方式:

方式一:用in操作符做类型守卫

通过检查对象是否包含目标属性,让TypeScript自动缩小类型范围,从而安全访问对应属性:

interface greetObject {
  text: string
}
interface errorObject {
  errorText: string,
}

async function callFetch(greeting: string): Promise<greetObject | errorObject> {
  try {
    return { text: greeting } as greetObject;
  } catch (error) {
    console.log(error);
    return { errorText: "there was an error" } as errorObject;
  }
}

submitButton.addEventListener("click", async (e: MouseEvent) => {
  e.preventDefault();
  const results = await callFetch(speechInput.value);
  
  if ("text" in results) {
    console.log(results.text);
  } else {
    console.log(results.errorText);
  }
})

方式二:添加判别式属性(更推荐)

给两个接口添加一个固定的字面量属性(比如type)作为类型标识,让TypeScript可以通过这个属性精准区分类型,这是处理联合类型最清晰、可维护性最高的方案:

interface greetObject {
  type: "success";
  text: string
}
interface errorObject {
  type: "error";
  errorText: string,
}

async function callFetch(greeting: string): Promise<greetObject | errorObject> {
  try {
    return { type: "success", text: greeting };
  } catch (error) {
    console.log(error);
    return { type: "error", errorText: "there was an error" };
  }
}

submitButton.addEventListener("click", async (e: MouseEvent) => {
  e.preventDefault();
  const results = await callFetch(speechInput.value);
  
  if (results.type === "success") {
    console.log(results.text);
  } else {
    console.log(results.errorText);
  }
})

这两种方案的优势

  • 完全保留TypeScript的类型检查能力,不会像any那样丢失类型约束
  • 不需要添加字符串索引签名,避免后续出现无提示的属性访问错误
  • 代码逻辑清晰,其他开发者能快速理解类型分支的处理逻辑

内容的提问来源于stack exchange,提问作者mainguy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:55:31