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

TypeScript实现根据首参数属性可选性条件要求第二参数的类型安全safeGet函数

问题根源

  1. 你调用safeGet<Person>()时仅显式传入了泛型T的类型,剩余泛型K、V都会使用定义的默认值:K默认是keyof Person联合类型,V默认是Person[keyof Person]即string | number | undefined,此时判断V extends null | undefined的结果为false,剩余参数类型永远是空数组,因此无论传入什么key都不接受第二个参数。
  2. 原有泛型设计没有让TS根据第一个入参key的实际值推导对应的K的精确类型,直接使用联合类型默认值导致条件类型判断失效。

正确实现

// 条件类型判断当前key是否需要传入默认值
type RequiredDefault<T, K extends keyof T> = undefined extends T[K] ? [NonNullable<T[K]>] : []

function safeGet<T, K extends keyof T>(key: K, ...defaultValue: RequiredDefault<T, K>) {
  return (obj: T) => {
    const val = obj[key]
    return val !== undefined ? val : defaultValue[0]
  }
}

效果校验

完全符合你给出的预期行为:

interface Person {
  name: string
  totalKids?: number
}

// 可选属性场景
safeGet<Person>('totalKids') // 报错:预期2个参数,仅收到1个
safeGet<Person>('totalKids', 4) // 校验通过
safeGet<Person>('totalKids', 'four') // 报错:string类型不能分配给number类型
safeGet<Person>('totalKids', undefined) // 报错:undefined不能分配给number类型

// 必选属性场景
safeGet<Person>('name') // 校验通过
safeGet<Person>('name', 'John') // 报错:预期1个参数,收到2个

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:54:04