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

TypeScript中能否实现通用属性检查类型守卫?

实现通用的属性检查类型守卫(TypeScript)

问题背景

我已经实现了针对单个属性的类型守卫,比如检查metadata属性的版本:

const hasMetadata = <T extends object>(obj: T): obj is T & {metadata: unknown} => (
    Object.hasOwn(obj, 'metadata')
)

但这类类型守卫需要写20多个,想做代码生成前,先确认TypeScript是否支持通用的属性检查类型守卫。我尝试了以下代码,但类型检查失败:

const hasProp = <T extends object>(obj: T, key: string): obj is T & {[key]: unknown} => (
    Object.hasOwn(obj, key)
)

报错信息:

A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type

解决方案

可以通过添加泛型参数捕获具体键名来实现通用版本。核心是让TypeScript推断出key的字面量类型,而非宽泛的string类型:

const hasProp = <T extends object, K extends string | number | symbol>(
    obj: T, 
    key: K
): obj is T & { [P in K]: unknown } => {
    return Object.hasOwn(obj, key);
};

原理说明

  • 新增泛型K,约束为string | number | symbol(对象键的合法类型),TypeScript会自动推断传入key的具体字面量类型(比如传入'metadata'时,K就是'metadata')。
  • 返回类型里的{ [P in K]: unknown }是映射类型,会根据K的具体值生成对应的属性类型,避免了原代码中计算属性名类型不明确的问题。

使用示例

interface User {
    id: number;
    name: string;
}

const user: User = { id: 1, name: 'Alice' };

if (hasProp(user, 'age')) {
    // 这里user会被推断为User & { age: unknown }
    console.log(user.age); // 类型合法
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:25:59