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

如何在TypeScript中为NaN、Infinity使用条件类型?

核心原因

TypeScript 截至 5.x 版本未将NaN、Infinity、-Infinity设为独立的字面量类型,上述值的静态类型会被统一推断为number,因此直接声明value: NaN的重载无法触发匹配,同时你当前的重载顺序也存在问题:TS 重载是从上到下优先匹配最先符合的规则,你把范围更大的number重载放在了细分重载前面,就算存在对应的细分类型也不会被命中。

可行实现方案

1. 烙印类型+重载顺序调整

首先定义专属烙印类型实现类型层面的区分:

type NaN = number & { __brand: 'nan' }
type Infinity = number & { __brand: 'infinity' }

调整重载顺序,将细分规则放在最前面:

// 细分规则优先
public static async type(value: NaN): Promise<'nan'>
public static async type(value: Infinity): Promise<'infinity'>
public static async type(value: number): Promise<'number' | 'nan' | 'infinity'>
public static async type(value: []): Promise<'array'>
public static async type(value: Promise<any>): Promise<'promise'>
// 其余重载省略
public static async type(value: any): Promise<T_detectType> {
  // 运行时逻辑不变,用原生方法判断即可
  if (typeof value === 'number') {
    if (Number.isNaN(value)) return 'nan' as T_detectType
    if (!Number.isFinite(value)) return 'infinity' as T_detectType
    return 'number' as T_detectType
  }
  // 其余类型判断逻辑
}

在明确入参为NaN/Infinity的场景下,添加对应类型断言即可触发精准类型提示:

const nanRes = await Utils.type(NaN as NaN) // 类型为 Promise<'nan'>
const infRes = await Utils.type(Infinity as Infinity) // 类型为 Promise<'infinity'>

2. 类型守卫自动收窄

如果需要在运行时判断后自动触发类型匹配,可以配套编写类型守卫函数:

function isNaN(val: number): val is NaN {
  return Number.isNaN(val)
}
function isInfinity(val: number): val is Infinity {
  return !Number.isFinite(val) && !Number.isNaN(val)
}

const input = Math.sqrt(-1)
if (isNaN(input)) {
  const res = await Utils.type(input) // 自动收窄为 Promise<'nan'>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:36:04