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

如何在运行时验证TypeScript接口的属性值合法性?

TypeScript 运行时校验对象是否符合接口(含枚举值验证)

我希望在运行时检查对象是否符合指定的TypeScript接口,要求对象的每个属性都拥有允许的值。

比如下面的代码,'nope'不是Switch枚举的有效值,编译时会报错,但我需要的是运行时校验:

enum Switch {
  'on',
  'off',
}

interface Foo {
  State: Switch
}

const f: Foo = {
  State: 'nope'
}

我原本以为类型谓词是可行方案,但发现它只能判断接口结构,没法验证属性值的有效性。比如下面的例子,传入无效值时校验仍然会通过:

enum Switch {
  'on',
  'warn',
}

interface Foo {
  Bar: number | Switch
}

const isValid = (foo: any): foo is Foo => {
  return (foo as Foo) !== undefined
}

console.log(isValid({ Bar: 'nope' })) // 输出 true,但实际值无效

请问有没有无需逐个遍历属性就能验证这些值的方法?


解决方案

首先明确:TypeScript的类型系统是编译时的,编译后所有类型信息都会被擦除,所以不可能完全不遍历属性/值就实现运行时校验——毕竟运行时根本没有接口的元数据可以直接读取。不过可以通过工具或代码生成来减少手动遍历的工作量:

1. 类型守卫+枚举校验(手动但可靠)

虽然需要遍历属性,但可以把枚举的校验逻辑封装起来,避免重复代码:

enum Switch {
  'on',
  'warn',
}

interface Foo {
  Bar: number | Switch
}

// 封装枚举的校验函数
const isSwitch = (val: unknown): val is Switch => {
  return Object.values(Switch).includes(val)
}

// 针对Foo的类型守卫
const isValidFoo = (foo: any): foo is Foo => {
  return (
    typeof foo === 'object' && foo !== null &&
    (typeof foo.Bar === 'number' || isSwitch(foo.Bar))
  )
}

console.log(isValidFoo({ Bar: 'nope' })) // 输出 false
console.log(isValidFoo({ Bar: Switch.on })) // 输出 true
console.log(isValidFoo({ Bar: 123 })) // 输出 true

2. 代码生成工具(自动生成校验逻辑)

如果不想手动写校验函数,可以用工具根据TypeScript接口自动生成运行时校验代码,比如:

  • 使用zod:先定义Zod schema,再导出对应的TypeScript类型,同时获得运行时校验能力
    import { z } from 'zod'
    
    const SwitchSchema = z.enum(['on', 'warn'])
    const FooSchema = z.object({
      Bar: z.union([z.number(), SwitchSchema])
    })
    
    // 自动导出TypeScript类型
    type Foo = z.infer<typeof FooSchema>
    
    // 运行时校验
    const result = FooSchema.safeParse({ Bar: 'nope' })
    console.log(result.success) // 输出 false
    
  • ts-pattern或io-ts也能实现类似效果,核心思路都是把类型定义和运行时校验逻辑绑定在一起,避免重复编写。

为什么不能“无需遍历”?

因为编译后的JavaScript里,interface Foo的类型信息完全消失了——枚举会被编译成对象,但接口连对象都不会生成。所以运行时根本没有“接口的属性列表”和“允许的属性值范围”可以直接读取,必须通过某种方式(手动写校验、工具生成校验)把这些信息编码到运行时代码里。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:15:01