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

TypeScript中as const意外取数组交集导致类型报错问题

TypeScript中as const导致includes类型错误的解决方案

当对硬编码数组使用as const断言后,在filter回调中调用i.foo.includes(3)会触发类型错误:Argument of type '3' is not assignable to parameter of type '2'.(2345),示例代码如下:

const data = [
  {
    foo: [1, 2],
  },
  {
    foo: [2, 3],
  },
] as const;

const result = data.filter((i) => {
  return i.foo.includes(3); // 类型错误
});

错误原因

as const会让TypeScript将数组推断为只读元组类型:第一个元素的foo类型是readonly [1, 2],第二个是readonly [2, 3]。数组的includes方法会基于元组元素类型约束参数:readonly [1,2]的includes只接受1或2,readonly [2,3]的includes只接受2或3。当i.foo是这两个元组的联合类型时,TypeScript会取两个includes参数类型的交集(也就是2),因此传入3会触发类型错误。

解决方案(无需放弃as const类型守卫)

方案1:自定义类型安全的includes辅助函数

编写通用函数,提取元组的所有可能值作为参数类型,既保证类型安全,又避开联合类型的限制:

const data = [
  {
    foo: [1, 2],
  },
  {
    foo: [2, 3],
  },
] as const;

// 提取元组的所有元素类型
type ValueOf<T> = T[keyof T];

function includes<T extends readonly unknown[]>(arr: T, val: ValueOf<T>): boolean {
  return (arr as readonly unknown[]).includes(val);
}

const result = data.filter((i) => {
  return includes(i.foo, 3); // 类型合法,且仅允许传入1/2/3
});

方案2:使用类型谓词实现精确类型推断

如果需要让result的类型精确到只包含foo含3的元素,可以用类型谓词:

const data = [
  {
    foo: [1, 2],
  },
  {
    foo: [2, 3],
  },
] as const;

// 定义包含目标值的元素类型
type HasFoo3 = typeof data[number] & { foo: readonly [2, 3] };

function hasFoo3(item: typeof data[number]): item is HasFoo3 {
  return item.foo.includes(3 as const);
}

const result = data.filter(hasFoo3);
// result的类型被精确推断为readonly [{ foo: readonly [2, 3] }]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:20:36