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

如何编写类型断言函数检查数组中所有Query是否均为Success状态?

解决TypeScript中isAllSuccess函数的类型断言问题

你遇到的错误是因为泛型约束和类型断言的结构不兼容,导致TypeScript无法确认断言类型可以分配给参数类型。下面是具体的分析和修复方案:

错误原因

  1. 原泛型T extends Array<Query<any>>过于宽泛,没有区分数组和元组的类型细节,导致TypeScript无法正确推断每个元素的具体Success类型。
  2. 断言类型{ [I in keyof T]: Success<T[I]> }存在逻辑问题:T[I]是Query<any>,生成的是Success<Query<any>>,而非你需要的Success<U>(U是原Query的TData类型)。
  3. readonly [...T]的写法和断言类型的数组结构不兼容,触发了TypeScript的类型分配检查错误。

修复方案

调整泛型约束和类型断言的写法,让TypeScript能正确提取每个Query元素的TData类型,并生成对应的Success元组类型:

type Success<T> = { status: 'success', data: T };
type Loading = { status: 'loading' };
type Query<T> = Success<T> | Loading;

const isAllSuccess = <T extends readonly Query<any>[]>(
  queries: T
): queries is { [I in keyof T]: T[I] extends Query<infer U> ? Success<U> : never } => {
  if (queries.length === 0) return false;
  return queries.every((q) => q.status === "success");
};

代码解释

  • 泛型约束:T extends readonly Query<any>[]覆盖了普通数组、元组以及只读数组的场景,确保参数可以是任意Query类型的集合。
  • 类型断言:使用条件类型T[I] extends Query<infer U> ? Success<U> : never,自动提取每个Query元素中隐含的TData类型U,将每个元素的类型窄化为对应的Success<U>,完美匹配你的需求。
  • 兼容性修复:直接使用T作为参数类型,避免了readonly [...T]带来的结构冲突,让TypeScript认可断言类型和参数类型的兼容性。

验证示例

// 模拟接口返回类型
type User = { id: number; name: string };
type Article = { title: string; content: string };

// 模拟异步请求钩子
const useFetchUser = (): Query<User> => ({ status: 'success', data: { id: 1, name: 'Alice' } });
const useFetchArticle = (): Query<Article> => ({ status: 'success', data: { title: 'TS技巧', content: '类型窄化' } });

const userQuery = useFetchUser();
const articleQuery = useFetchArticle();

if (isAllSuccess([userQuery, articleQuery])) {
  // 此处userQuery自动推断为Success<User>,articleQuery为Success<Article>
  console.log(userQuery.data.name, articleQuery.data.title);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:17:22