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

TypeScript中能否在不重复代码的前提下进行类型断言?

TypeScript类型断言优化:避免重复代码

我编写了如下代码,能看到当前方案存在的问题:

type Keys = "foo" | "bar";

type Item = {
  id: string;
}

type Dated = {
  date: string;
  item: Item
}

function isItem(param: any): param is Item {
  if (!param) return false;
  return (param as Item).id !== undefined;
}

type AddDated = {
  item: string | Dated;
  key: Extract<Keys, "foo">
}

type AddNonDated = {
  item: Item;
  key: Extract<Keys, "bar">
}

function addItem(payload: AddDated | AddNonDated) {
  // Do something
}

function manageItem(item: AddDated["item"] | AddNonDated["item"], key: Keys) {
  if (isItem(item) && key === "bar") {
    addItem({
      item: item,
      key
    })
  } else if (!isItem(item) && key === "foo") {
    addItem({
      item: item,
      key
    })
  }
}

我想了解的是,能否在manageItem函数中实现类型断言,同时避免重复编写使用断言后变量的代码?


解决方案

可以通过以下几种方式实现,既保证类型安全,又避免重复代码:

方案1:抽离合法参数到临时变量

先通过条件判断确认参数组合的合法性,将合法的{item, key}存入临时变量,最后统一调用addItem:

function manageItem(item: AddDated["item"] | AddNonDated["item"], key: Keys) {
  let validPayload: AddDated | AddNonDated | undefined;

  if (isItem(item) && key === "bar") {
    validPayload = { item, key };
  } else if (!isItem(item) && key === "foo") {
    validPayload = { item, key };
  }

  if (validPayload) {
    addItem(validPayload);
  }
}

方案2:自定义精准类型守卫

创建一个专门的类型守卫,直接验证item和key的组合是否符合addItem的参数要求,之后统一调用:

function isValidAddPayload(
  item: AddDated["item"] | AddNonDated["item"], 
  key: Keys
): item is (AddNonDated["item"] & { _key: "bar" }) | (AddDated["item"] & { _key: "foo" }) {
  return (isItem(item) && key === "bar") || (!isItem(item) && key === "foo");
}

function manageItem(item: AddDated["item"] | AddNonDated["item"], key: Keys) {
  if (isValidAddPayload(item, key)) {
    addItem({ item, key } as AddDated | AddNonDated);
  }
}

方案3:利用条件类型简化断言

直接在条件判断后,通过条件类型推断参数的具体类型,一次性完成断言和调用:

function manageItem(item: AddDated["item"] | AddNonDated["item"], key: Keys) {
  if ((isItem(item) && key === "bar") || (!isItem(item) && key === "foo")) {
    addItem({ 
      item, 
      key 
    } as typeof item extends Item ? AddNonDated : AddDated);
  }
}

这些方案的核心都是先确认参数组合的合法性,再将重复的addItem调用逻辑合并到一处,同时通过TypeScript的类型推断或显式断言让编译器认可参数的类型合法性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:25:22