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

升级TypeScript 4.9.3至5.1.3时遇随机类型错误求助

TypeScript 5.1.3升级后Yup校验的类型错误解决

问题背景

将项目从TypeScript 4.9.3升级到5.1.3后,遇到一个诡异的类型错误:

  • VS Code和WebStorm都会触发错误,但在文件内做简单编辑(比如敲空格)后,IDE里的错误会暂时消失
  • 命令行执行tsc检查时,错误始终存在
  • 本地TSC版本及项目依赖均已更新至5.1.3

相关代码:

const ShortCodeSchema = Yup.object().shape({
  code: Yup.string()
    .min(3)
    .matches(/^((?!\/).)*$/),
  languageId: Yup.string().optional(),
});

const schema = Yup.object().shape({
  title: Yup.string().required("admin.snippets.drawer.validation.name"),
  shortCodes: Yup.array(ShortCodeSchema).test(
    "shortcodes",
    "admin.snippets.drawer.validation.no_deplicate_shortcode",
    (shortCodes) => {
      const counts = shortCodes?.reduce((acc, shortCode) => {
        if (shortCode?.code && acc.has(shortCode.code)) {
          acc.set(shortCode.code, acc.get(shortCode.code)! + 1);
        } else if (shortCode?.code) {
          acc.set(shortCode.code, 1); 
        }
        return acc;
      }, new Map<string, number>());

      const hasDuplicates =
        typeof [...(counts ?? []).values()].find((count) => count > 1) === "number";

      return !hasDuplicates;
    }
  ),
});

问题原因

TS 5.x对类型推断的严格性大幅提升,这里核心有两个问题:

  1. Yup的test函数参数shortCodes被推断为模糊的联合类型,TS无法确定其具体结构
  2. counts ?? []的写法存在类型不兼容:counts是Map<string, number> | undefined,和数组类型不匹配,TS 5.x会严格拦截这种类型歧义

修复方案

直接修改代码消除类型歧义,优化逻辑:

1. 显式定义类型并约束参数

提前定义ShortCode类型,给test函数的参数指定明确类型,避免TS推断混乱:

type ShortCode = { code?: string; languageId?: string };

2. 处理空值并统一类型

去掉冗余的可选链,先判断shortCodes是否存在;将counts ?? []改为counts ?? new Map(),保证类型统一。

3. 优化重复判断逻辑

用更简洁的some方法替代原有的类型判断写法,同时保证类型安全。

修改后的完整代码:

const ShortCodeSchema = Yup.object().shape({
  code: Yup.string()
    .min(3)
    .matches(/^((?!\/).)*$/),
  languageId: Yup.string().optional(),
});

type ShortCode = { code?: string; languageId?: string };

const schema = Yup.object().shape({
  title: Yup.string().required("admin.snippets.drawer.validation.name"),
  shortCodes: Yup.array(ShortCodeSchema).test(
    "shortcodes",
    "admin.snippets.drawer.validation.no_deplicate_shortcode",
    (shortCodes: ShortCode[]) => {
      // 先处理空数组情况
      if (!shortCodes) return true;

      const counts = shortCodes.reduce((acc, shortCode) => {
        if (shortCode?.code) {
          acc.set(shortCode.code, (acc.get(shortCode.code) || 0) + 1);
        }
        return acc;
      }, new Map<string, number>());

      // 检查是否有重复项
      const hasDuplicates = Array.from(counts.values()).some(count => count > 1);

      return !hasDuplicates;
    }
  ),
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:05:41