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

TypeScript中如何实现支持null入参的带类型收窄自定义谓词函数?

TypeScript 谓词函数类型缩窄避坑方案

你遇到的问题本质是类型谓词的范围定义太宽泛,导致TS在else分支做了过度缩窄,可通过以下几种方案解决:

  • 方案1:使用精准子类型谓词
    如果你的Shape是可辨识联合类型,直接将类型谓词指定为Blobby对应的子类型即可,同时会自动排除null场景:
type Shape = Blobby | Rect | Circle
interface Blobby {
  type: 'blobby'
  color: string
  blobRadius: number
}
interface Rect {
  type: 'rect'
  width: number
  height: number
}
interface Circle {
  type: 'circle'
  radius: number
}

function isBlobby(s: Shape | null): s is Blobby {
  return s?.type === 'blobby'
}

// 调用示例
const x: Shape | null = getShape()
if (isBlobby(x)) {
  doSomethingWith(x.color) // 无需非空断言
} else {
  // 此处x类型为 Rect | Circle | null,不会被错误缩窄为null
}
  • 方案2:为非联合类型构造交叉类型谓词
    如果Shape是普通接口,没有定义可辨识联合,可以直接在类型谓词中声明Blobby形态需要满足的属性约束:
interface Shape {
  type?: string
  color?: string
  radius?: number
}

function isBlobby(s: Shape | null): s is Shape & { type: 'blobby', color: string } {
  return s != null && s.type === 'blobby' && typeof s.color === 'string'
}

该方案的使用效果和可辨识联合方案完全一致,else分支不会出现过度缩窄问题。

  • 方案3:不修改谓词的轻量适配写法
    如果你不想调整原有isBlobby的返回类型定义,可以在判断时额外加一层非空校验,TS会自动完成类型缩窄:
// 保持原有谓词定义不变
function isBlobby(s: Shape | null): boolean {
  return s != null && s.type === 'blobby'
}

const x: Shape | null = getShape()
if (x && isBlobby(x)) {
  doSomethingWith(x.color) // 无需非空断言
} else {
  // x类型仍保持为 Shape | null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:48:00