面试题答案
一键面试- 类型注解兼容性规则:
- 在TypeScript中,子类型(这里
B
继承自A
,B
是子类型,A
是父类型)与父类型是兼容的。这意味着一个函数期望接受类型A
的参数,那么可以传入类型B
的对象。因为B
继承自A
,B
拥有A
的所有属性和方法,所以从类型系统的角度看,B
类型的对象可以安全地当作A
类型的对象使用。
- 在TypeScript中,子类型(这里
- 运行时可能出现的情况:
- 如果
func
函数只依赖于A
接口定义的属性和方法,那么运行时不会出现问题。例如,如果A
接口定义了methodA
方法,func
函数调用methodA
,而B
实现了methodA
,那么一切正常。 - 但是,如果
func
函数尝试访问B
特有的属性或方法(这些属性或方法在A
接口中不存在),运行时就会出错。比如B
有一个methodB
方法,但A
没有,func
函数中调用methodB
就会导致运行时错误,因为在类型系统层面,函数只期望接受A
类型,它不知道传入的对象实际上是B
类型且有methodB
方法。
- 如果
- 在TypeScript层面进行预防:
- 类型断言:如果确定传入的对象是
B
类型,可以在函数内部进行类型断言。例如:
interface A { methodA: () => void; } interface B extends A { methodB: () => void; } function func(a: A) { if ('methodB' in a) { const b = a as B; b.methodB(); } } const bObj: B = { methodA: () => console.log('Method A'), methodB: () => console.log('Method B') }; func(bObj);
- 使用类型守卫:也可以通过自定义类型守卫函数来确保对象的类型。例如:
interface A { methodA: () => void; } interface B extends A { methodB: () => void; } function isB(a: A): a is B { return'methodB' in a; } function func(a: A) { if (isB(a)) { a.methodB(); } } const bObj: B = { methodA: () => console.log('Method A'), methodB: () => console.log('Method B') }; func(bObj);
- 类型断言:如果确定传入的对象是