面试题答案
一键面试- 赋值原因:
- 在TypeScript中,接口遵循结构类型系统。
InterfaceB
包含了InterfaceA
的所有属性(a
和b
,且类型相同),因此从结构上看,InterfaceB
类型的对象满足InterfaceA
的结构要求,所以可以赋值给InterfaceA
类型的变量。
- 在TypeScript中,接口遵循结构类型系统。
- 利弊分析:
- 利:
- 灵活性:这种兼容性使得代码更加灵活。例如,在函数参数类型定义中,如果函数接受
InterfaceA
类型的参数,那么实际上也可以传入InterfaceB
类型的对象,这样在不修改函数定义的情况下,可以接受更多符合一定结构的对象,减少了重复代码。 - 扩展性:有利于代码的扩展。当需要在原有的接口基础上添加新属性时,只要新接口包含旧接口的所有属性,就可以继续使用原来依赖旧接口的代码,而无需大量修改。
- 灵活性:这种兼容性使得代码更加灵活。例如,在函数参数类型定义中,如果函数接受
- 弊:
- 潜在的类型错误:由于
InterfaceB
类型对象赋值给InterfaceA
类型变量后,在使用该变量时,TypeScript编译器不会检查InterfaceB
特有的属性(如c
),如果代码中意外地访问了c
属性,可能会导致运行时错误。 - 可读性降低:从代码阅读角度,可能会让阅读者困惑为什么一个可能包含更多属性的对象能赋值给一个看起来属性更少的类型变量,增加了理解代码的难度。
- 潜在的类型错误:由于
- 利:
- 避免潜在问题的示例:
- 类型断言:
interface InterfaceA { a: string; b: number; } interface InterfaceB { a: string; b: number; c: boolean; } const objB: InterfaceB = { a: 'test', b: 1, c: true }; const objA: InterfaceA = objB; // 如果需要访问c属性,可以先进行类型断言 if ((objA as InterfaceB).c) { console.log('c is true'); }
- 使用类型守卫:
function isInterfaceB(obj: InterfaceA | InterfaceB): obj is InterfaceB { return (obj as InterfaceB).c!== undefined; } const objB: InterfaceB = { a: 'test', b: 1, c: true }; const objA: InterfaceA = objB; if (isInterfaceB(objA)) { console.log(objA.c); }
- 类型断言: