面试题答案
一键面试- 如果实际传入的对象结构与接口不完全匹配会发生什么:
- 在TypeScript中,类型断言只是告诉编译器“相信我,这个值就是这个类型”,并不会在运行时进行实际的类型检查。所以如果实际传入的对象结构与接口不完全匹配,在编译阶段不会报错(因为有类型断言),但在运行时可能会因为访问不存在的属性等操作而导致错误。
- 代码示例:
interface User { name: string; age: number; } function printUser(user: any) { const userObj = user as User; console.log(userObj.name, userObj.age); } // 传入结构不完全匹配的对象 const wrongUser = { name: 'John' }; printUser(wrongUser);
- 在上述代码中,
wrongUser
缺少age
属性,但由于类型断言user as User
,编译不会报错。然而在运行时,访问userObj.age
会得到undefined
,如果后续代码依赖age
属性进行计算等操作,就会引发运行时错误。
- 在上述代码中,
- 如何避免潜在的运行时错误:
- 使用类型保护:
interface User { name: string; age: number; } function isUser(obj: any): obj is User { return 'name' in obj && 'age' in obj; } function printUser(user: any) { if (isUser(user)) { console.log(user.name, user.age); } else { console.log('The object does not match the User interface'); } } const wrongUser = { name: 'John' }; printUser(wrongUser);
- 在上述代码中,通过
isUser
函数作为类型保护,在使用对象前先检查其结构是否符合User
接口,这样可以避免运行时错误。
- 在上述代码中,通过
- 使用
assert
函数(在支持assert
的环境中):interface User { name: string; age: number; } function assertUser(user: any): User { if (!('name' in user && 'age' in user)) { throw new Error('The object does not match the User interface'); } return user as User; } function printUser(user: any) { try { const userObj = assertUser(user); console.log(userObj.name, userObj.age); } catch (error) { console.error(error.message); } } const wrongUser = { name: 'John' }; printUser(wrongUser);
- 这里
assertUser
函数检查对象结构,如果不符合则抛出错误,在printUser
函数中通过try - catch
捕获错误,从而避免运行时的意外错误。
- 这里
- 使用类型保护: