面试题答案
一键面试TypeScript 对这种情况的处理
在TypeScript中,当将{name: string, age: number}
类型的对象字面量传递给processData
函数,该函数期望的参数类型是{name: string}
,TypeScript会进行额外属性检查。由于对象字面量直接作为参数传递,并且它包含了processData
函数参数类型中未定义的age
属性,TypeScript会报错,提示存在额外属性age
。
额外属性检查局限性在函数参数传递场景下的体现
- 对象字面量直接传递受限:如果是对象字面量直接作为参数传递给函数,TypeScript会严格检查额外属性,即使对象字面量中的属性在实际运行时不会对函数逻辑造成问题,也会报错。例如:
function processData(data: {name: string}) {
console.log(data.name);
}
// 报错:对象字面量中不能有未声明的属性 'age'
processData({name: 'John', age: 30});
- 不利于灵活性:这种严格检查在某些场景下会限制代码的灵活性,比如当我们确实希望传递一个包含更多属性的对象给只需要部分属性的函数时,直接传递对象字面量会被阻止。
绕过这种检查但又能保证类型安全的方法
- 类型断言:可以使用类型断言将对象字面量断言为函数参数期望的类型。这样TypeScript会信任开发者的判断,绕过额外属性检查。
function processData(data: {name: string}) {
console.log(data.name);
}
processData({name: 'John', age: 30} as {name: string});
- 使用变量:先将对象字面量赋值给一个变量,然后传递该变量给函数。因为TypeScript不会对变量进行额外属性检查,只要变量的类型兼容函数参数类型即可。
function processData(data: {name: string}) {
console.log(data.name);
}
let obj = {name: 'John', age: 30};
processData(obj);
- 接口继承:定义一个接口继承自函数参数期望的类型接口,并添加额外属性。然后使用这个接口来定义对象,最后传递对象给函数。
interface BaseData {
name: string;
}
interface ExtendedData extends BaseData {
age: number;
}
function processData(data: BaseData) {
console.log(data.name);
}
let extendedObj: ExtendedData = {name: 'John', age: 30};
processData(extendedObj);