TypeScript编译后运行时是否会进行变量类型检查?
核心原因
你遇到的现象本质是两个机制共同导致的:
- TypeScript 没有运行时类型检查能力
所有TS的类型标注、类型声明只会在代码编译阶段做静态校验,编译完成后产出的纯JavaScript代码会擦除全部类型相关的代码,运行时根本不会感知你之前给id标过number类型,自然不会因为实际拿到字符串就抛错。路径参数从HTTP请求里取出来的时候默认全是字符串类型,你不手动做转换的话,哪怕标了number,运行时拿到的永远是字符串值。 - 你写的参数类型标注属于类型断言,绕开了编译期检查
@Param()装饰器的默认返回值类型是any,你在解构时手动标注{ id: number; course_id: string },相当于主动给编译器做保证:“我确认这里取出来的id是数字类型”,TS编译器不会去推演请求实际传值的类型,会直接采信你写的声明,所以编译阶段也不会给你报类型不匹配的警告。
推荐处理方案
不要依赖TS类型标注做请求参数的校验,所有外部传入的参数都要做显式的运行时校验/转换,针对这个场景有两种常用实现:
- 手动转换+校验:拿到id后手动调用
Number(id)做类型转换,自行判断转换结果是否为合法数字,不合法就返回参数错误 - 使用Nest内置管道做自动转换:Nest自带的
ParseIntPipe可以在取参时自动把字符串参数转为数字,转换失败会自动抛出400格式错误,代码示例如下:
@Delete('users/:id/courses/:course_id') deleteUserCourses( @Param('id', ParseIntPipe) id: number, @Param('course_id') course_id: string, ) { return this.usersService.deleteUserCourses(id, course_id); }
提示:如果需要做更复杂的请求参数校验(比如请求体格式、字段规则),可以配合class-validator+class-transformer做全局的参数校验,不用在每个接口里手动写判断逻辑。
内容的提问来源于stack exchange,提问作者Hawkeyebrow
相关产品推荐
相关产品推荐

