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

TypeScript中如何在类型断言失败时抛出错误?

问题核心说明

TypeScript 的类型仅存在于编译阶段,运行时会被完全擦除,所以你想要的 isInType<School[]>() 这种直接基于泛型参数的运行时校验逻辑无法直接实现——因为运行时根本不知道 School 的结构细节。

要解决 API 响应类型不匹配的问题,必须结合运行时可执行的校验逻辑和 TypeScript 的类型系统,以下是两种可行方案:


方案1:手动编写类型守卫函数

通过自定义类型守卫函数,在运行时检查值的结构,同时让 TypeScript 在编译阶段识别校验后的类型。

// 先定义你的TS类型
type School = {
  id: number;
  name: string;
  address?: string;
};

type User = {
  id: number;
  username: string;
  email: string;
};

// 单个School的类型守卫:检查必要字段的类型
function isSchool(obj: unknown): obj is School {
  if (typeof obj !== 'object' || obj === null) return false;
  const school = obj as School;
  return typeof school.id === 'number' && typeof school.name === 'string';
}

// 扩展为数组类型的守卫:检查数组每一项都符合School类型
function isSchoolArray(arr: unknown): arr is School[] {
  if (!Array.isArray(arr)) return false;
  return arr.every(item => isSchool(item));
}

// 使用示例
async function fetchSchools() {
  const response = await fetch("https://test.api.com/Users");
  const json = await response.json(); // 注意:原代码漏写了await!

  if (!isSchoolArray(json)) {
    throw new Error("响应类型不匹配:预期为School[]");
  }

  // 此处json会被TS自动推断为School[]类型
  console.log(json);
}

这种方式无需额外依赖,但需要手动为每个目标类型编写校验逻辑,适合结构简单的场景。


方案2:用代码生成工具自动生成校验逻辑

如果不想手动编写重复的校验代码,可以用工具从 TypeScript 类型自动生成运行时校验规则,或者反过来先写校验规则再生成 TS 类型(避免重复劳动)。以 zod 为例:

import { z } from 'zod';

// 先编写运行时的校验schema
const SchoolSchema = z.object({
  id: z.number(),
  name: z.string(),
  address: z.string().optional()
});

// 从schema自动生成TS类型
type School = z.infer<typeof SchoolSchema>;

// 数组类型的schema
const SchoolArraySchema = SchoolSchema.array();

// 使用示例
async function fetchSchools() {
  const response = await fetch("https://test.api.com/Users");
  const json = await response.json();

  // 安全校验:失败时返回错误信息,不直接抛出
  const validateResult = SchoolArraySchema.safeParse(json);
  if (!validateResult.success) {
    throw new Error(`响应类型不匹配:${validateResult.error.message}`);
  }

  // validateResult.data 会被TS推断为School[]类型
  console.log(validateResult.data);
}

这种方式只需要维护一份校验规则,同时得到 TS 类型和运行时校验能力,适合复杂类型或多场景复用的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:37:41