TypeScript反序列化JSON时使用类与接口有什么区别?
TypeScript JSON反序列化标注接口与类的差异说明
首先明确核心前提:JSON.parse() 返回的是无自定义原型的普通JavaScript对象,不会自动生成类实例,也不会携带类上定义的方法。
两种写法的核心区别如下:
标注为 IBar 接口类型
var baz:IBar = JSON.parse(jsonString);
- 属于编译期的结构校验:只要
JSON.parse返回的对象属性结构匹配IBar的定义(包含number类型的x属性、可选string类型的y属性),编译阶段就不会报错。 - 无运行时额外开销:TypeScript接口会在编译后完全擦除,不会生成任何冗余JS代码,仅用于编译时的类型检查。
- 完全适配JSON反序列化场景:JSON本身只承载数据结构,不包含类的行为逻辑,用接口标注仅校验结构是最合理的用法。
标注为 Bar 类类型
var baz:Bar = JSON.parse(jsonString);
- 仅在你的
Bar类只有属性定义、没有自定义方法时,编译阶段不会报错,因为二者结构完全匹配。但这种写法存在隐性风险:- 如果你后续给
Bar类新增了自定义方法,比如:
编译阶段会认为class Bar { x:number; y?:string; getX() { return this.x } }baz作为Bar实例拥有getX方法,但实际运行时调用baz.getX()会直接抛出错误,因为JSON.parse返回的纯对象没有继承Bar的原型链,根本不存在这个方法。 - 类定义会在编译后保留对应的JS构造函数代码,如果你没有主动调用
new Bar()创建实例,仅给纯对象标注类类型,本质是不符合实际运行逻辑的错误类型标注。
- 如果你后续给
类实例反序列化的正确写法
如果你确实需要得到Bar的实例,需要手动做实例转换,不能直接给JSON.parse的结果标注Bar类型:
const raw = JSON.parse(jsonString); const baz = Object.assign(new Bar(), raw); // 此时baz为真正的Bar实例,可正常调用类方法
内容的提问来源于stack exchange,提问作者CSharp-n
相关产品推荐
相关产品推荐

