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

TypeScript条件检查后无法推断类型含指定属性的问题解决

TypeScript条件检查后无法识别data.token属性的解决方案

问题代码

type MyFunctions = {
  play(): void
  pause(args: { reset: boolean }): void
  stop(args: { restart: boolean }): void
}

type AuthStruct = {
  [K in keyof MyFunctions]: {
    requiresAuth: boolean
  }
}

const auth = {
  play: {
    requiresAuth: true
  },
  pause: {
    requiresAuth: true
  },
  stop: {
    requiresAuth: false
  }
} as const satisfies AuthStruct

type Auth = typeof auth

type FunctionParameters<K extends keyof MyFunctions> = Parameters<
  MyFunctions[K]
>[0] extends undefined
  ? never
  : Parameters<MyFunctions[K]>[0]

type Data<K extends keyof MyFunctions> = (FunctionParameters<K> extends never
  ? {}
  : FunctionParameters<K>
) & (
    Auth[K] extends { requiresAuth: true }
    ? { token: string }
    : {}
  )

function runFunction<F extends keyof MyFunctions>(
  func: F,
  data: Data<F>
) {
  if(auth[func].requiresAuth) {
    data.token // 此处编译器无法识别token属性
  }
}

问题描述

执行if(auth[func].requiresAuth)条件检查后,TypeScript编译器无法识别data包含token属性,甚至用data.token!强制断言也无效,该如何解决?

解决方案

原因分析

TypeScript无法通过auth[func].requiresAuth的运行时检查,反向推导泛型F的具体类型分支。auth是const断言后的常量,但泛型F是keyof MyFunctions的子集,编译器无法将auth[F]['requiresAuth']的布尔值与Data<F>的结构建立关联,因此无法细化data的类型。

具体解决方法:使用类型守卫函数

编写一个自定义类型守卫,将func的类型与requiresAuth的布尔值绑定,让编译器能通过条件检查细化data的类型:

// 自定义类型守卫:判断当前func是否需要认证
function requiresAuth<F extends keyof MyFunctions>(
  func: F
): func is Extract<F, { 
  [K in keyof MyFunctions]: Auth[K]['requiresAuth'] extends true ? K : never 
}[keyof MyFunctions]> {
  return auth[func].requiresAuth;
}

// 修改后的runFunction
function runFunction<F extends keyof MyFunctions>(
  func: F,
  data: Data<F>
) {
  if(requiresAuth(func)) {
    data.token; // 编译器现在能正确识别token属性
    console.log(data.token);
  } else {
    // 此处data不包含token属性,编译器也能正确推断
    console.log(data);
  }
}

原理说明

类型守卫函数requiresAuth返回布尔值的同时,告诉编译器:当返回true时,func的类型是MyFunctions中所有requiresAuth为true的键(即'play'|'pause')。此时编译器会自动将Data<F>细化为包含token的类型分支,从而正确识别data.token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:50:53