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

如何从NavigationGuard类型提取参数并省略next参数?

基于NavigationGuard类型移除next参数生成新类型的解决方案

原始类型定义

export declare interface NavigationGuard {
    (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext): NavigationGuardReturn | Promise<NavigationGuardReturn>;
}

需求

需要生成一个移除next参数的新类型,最终期望的类型结构如下:

export type SomeNavigationGuardType = (to: RouteLocationNormalized, from: RouteLocationNormalized) => NavigationGuardReturn | Promise<NavigationGuardReturn>;

尝试的写法及问题

尝试使用Parameters工具类型提取参数,再用Omit移除next参数,但Parameters返回的是元组类型,而Omit仅适用于对象类型,无法直接操作元组,因此两种写法均报错:

第一种写法

type NavigationGuardParams = Omit<Parameters<NavigationGuard>, 'next'>

export type UseRouterNivigationGuards = {
  beforeEach?: (arg: NavigationGuardParams) => ReturnType<NavigationGuard>
  beforeResolve?: (arg: NavigationGuardParams) => ReturnType<NavigationGuard>
  afterEach?: NavigationHookAfter
}

错误提示:Expected 1 arguments, but got 2.

第二种写法

type NavigationGuardParams = Omit<Parameters<NavigationGuard>, 'next'>

export type UseRouterNivigationGuards = {
  beforeEach?: (...arg: NavigationGuardParams) => ReturnType<NavigationGuard>
  beforeResolve?: (...arg: NavigationGuardParams) => ReturnType<NavigationGuard>
  afterEach?: NavigationHookAfter
}

错误提示:Argument of type '[RouteLocationNormalized, RouteLocationNormalized]' is not assignable to parameter of type 'NavigationGuardParams'.

正确解决方案

利用TypeScript的条件类型+infer关键字提取元组的前两个元素,因为Parameters<NavigationGuard>返回的元组是[RouteLocationNormalized, RouteLocationNormalized, NavigationGuardNext],我们只需要保留前两项:

步骤1:定义移除next后的参数元组

// 提取NavigationGuard的前两个参数,忽略第三个next参数
type NavigationGuardWithoutNextParams = Parameters<NavigationGuard> extends [infer To, infer From, ...any[]] 
  ? [To, From] 
  : never;

步骤2:定义新的守卫类型

// 基于提取的参数元组,生成目标函数类型
type SomeNavigationGuardType = (...args: NavigationGuardWithoutNextParams) => ReturnType<NavigationGuard>;

步骤3:更新UseRouterNivigationGuards类型

export type UseRouterNivigationGuards = {
  beforeEach?: SomeNavigationGuardType;
  beforeResolve?: SomeNavigationGuardType;
  afterEach?: NavigationHookAfter;
};

简化写法(无需单独抽类型)

也可以直接在对象类型中内联定义:

export type UseRouterNivigationGuards = {
  beforeEach?: (...args: Parameters<NavigationGuard> extends [infer To, infer From, ...any[]] ? [To, From] : never) => ReturnType<NavigationGuard>;
  beforeResolve?: (...args: Parameters<NavigationGuard> extends [infer To, infer From, ...any[]] ? [To, From] : never) => ReturnType<NavigationGuard>;
  afterEach?: NavigationHookAfter;
};

内容的提问来源于stack exchange,提问作者Micheal J. Roberts

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:07:08