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

TypeScript中如何传播类型守卫?复用逻辑时传递类型谓词

复用类型守卫逻辑并传播类型谓词

要实现调用expectToken后自动窄化token的类型,你可以通过泛型+类型守卫函数的类型约束来提取并传播guardfn的类型谓词,具体改造如下:

改造后的代码

type TokenType = `NumericLiteral`; // 可扩展为更大的联合类型

interface Token {
  type: TokenType;
  raw: string;
  value?: unknown;
}

interface NumericLiteral extends Token {
  type: `NumericLiteral`;
  value: number;
}

function isNumericLiteral(token: Token): token is NumericLiteral {
  return token.type === `NumericLiteral`;
}

// 泛型T表示守卫后得到的具体Token子类型
function expectToken<T extends Token>(
  token: Token | undefined,
  type: TokenType,
  guardfn: (token: Token) => token is T
): asserts token is T { // 使用asserts语法声明参数的类型断言
  if (!token || !guardfn(token)) {
    const received = token ? token.type : `nothing`;
    throw new Error(`Expected ${type} but got ${received}`);
  }
}

const token = { type: `NumericLiteral`, value: 123 } as Token;
expectToken(token, `NumericLiteral`, isNumericLiteral); 
// 此时token已被窄化为NumericLiteral类型,可以直接访问value属性
console.log(token.value.toFixed(2)); // 类型检查通过

关键改动说明

  • 泛型T约束:用T extends Token指定守卫函数最终要断言的目标子类型,让TypeScript能关联guardfn的类型谓词和输入参数的类型。
  • 类型守卫函数参数:将guardfn的类型从普通布尔返回值改为(token: Token) => token is T,明确告知TypeScript这个函数是用于将Token断言为T的类型守卫。
  • asserts类型断言:函数返回值使用asserts token is T语法,这是TypeScript的断言函数特性,表明如果函数正常执行(不抛出错误),则输入的token必然是T类型,从而实现调用后的自动类型窄化。

这种方式不仅能复用通用的校验逻辑,还能完美保留类型守卫的类型推导能力,适用于所有Token子类型的守卫函数复用。

内容的提问来源于stack exchange,提问作者Adam B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:02:36