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

如何排除值为undefined并精简嵌套if/else代码?

问题描述

我有一段可正常运行的代码:

(err, resp) => {
  if (resp) {
    if (resp.missing) {
      resolve(new CacheListFetch.Miss());
    } else if (resp.found) {
      resolve(new CacheListFetch.Hit(resp.found.values));
    } else {
      resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
    }
  } else {
    resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
  }
}

为了消除重复的错误处理分支,遵循DRY原则,我尝试了如下重构:

(err, resp) => {
  switch (true) {
    case typeof resp === 'undefined':
    default:
      resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
      break;
    case resp.missing instanceof
      cache_client._ListFetchResponse._Missing:
      resolve(new CacheListFetch.Miss());
      break;
    case resp.found instanceof cache_client._ListFetchResponse._Found:
      resolve(new CacheListFetch.Hit(resp.found.values));
      break;
  }
}

但TypeScript的ESLint持续提示resp可能为undefined,尽管对应分支中resp不可能是undefined:

src/internal/cache-client.ts:303:18 - error TS18048: 'resp' is possibly 'undefined'.

303             case resp.missing instanceof
                     ~~~~

src/internal/cache-client.ts:307:18 - error TS18048: 'resp' is possibly 'undefined'.

307             case resp.found instanceof cache_client._ListFetchResponse._Found:
                     ~~~~

src/internal/cache-client.ts:308:46 - error TS18048: 'resp' is possibly 'undefined'.

308               resolve(new CacheListFetch.Hit(resp.found.values));
                                                 ~~~~

请问如何实现代码精简并解决该类型提示问题?

解决方案

方法一:提前处理错误分支,缩小类型范围

先单独处理resp为undefined的情况,后续逻辑中TypeScript会自动推断resp非undefined,同时消除重复代码:

(err, resp) => {
  if (!resp) {
    resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
    return;
  }

  if (resp.missing instanceof cache_client._ListFetchResponse._Missing) {
    resolve(new CacheListFetch.Miss());
  } else if (resp.found instanceof cache_client._ListFetchResponse._Found) {
    resolve(new CacheListFetch.Hit(resp.found.values));
  } else {
    resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
  }
}

方法二:类型守卫+Switch结构

若偏好Switch写法,同样先通过提前return完成类型收窄,再处理分支:

(err, resp) => {
  if (!resp) {
    resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
    return;
  }

  switch (true) {
    case resp.missing instanceof cache_client._ListFetchResponse._Missing:
      resolve(new CacheListFetch.Miss());
      break;
    case resp.found instanceof cache_client._ListFetchResponse._Found:
      resolve(new CacheListFetch.Hit(resp.found.values));
      break;
    default:
      resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
      break;
  }
}

方法三:非空断言(不推荐)

如果必须保留原Switch结构,可使用非空断言!强制告诉TypeScriptresp非undefined,但这种方式会跳过类型检查,存在潜在风险,仅在逻辑绝对确定时使用:

(err, resp) => {
  switch (true) {
    case typeof resp === 'undefined':
    default:
      resolve(new CacheListFetch.Error(cacheServiceErrorMapper(err)));
      break;
    case resp!.missing instanceof cache_client._ListFetchResponse._Missing:
      resolve(new CacheListFetch.Miss());
      break;
    case resp!.found instanceof cache_client._ListFetchResponse._Found:
      resolve(new CacheListFetch.Hit(resp!.found.values));
      break;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:50:30