面试题答案
一键面试function processData(data: DataUnion): string | number | boolean {
if (data.type === 'A') {
return data.value.split('').reverse().join('');
} else if (data.type === 'B') {
return data.value.reduce((acc, cur) => acc + cur, 0) / data.value.length;
} else if (data.type === 'C') {
return!data.value;
}
// 防止遗漏分支,这里也可以抛出异常等
return null as any;
}
可能出现的类型收缩相关的陷阱
- 遗漏分支:如果新增了
DataUnion
的联合类型分支,但processData
函数没有相应更新处理逻辑,就会出现处理逻辑不完整的情况。例如新增{ type: 'D', value: { prop: string } }
,函数就没有处理type === 'D'
的情况。 - 类型判断错误:在类型收缩时,判断条件写错可能导致类型没有正确收缩。例如写成
if (data.type === 'a')
(注意这里是小写a
),就无法正确处理type === 'A'
的情况。
优化代码以避免这些陷阱的方法
- 使用
never
类型检查遗漏分支:可以在函数最后添加一个default
分支,让TypeScript检查是否有遗漏的联合类型分支。例如:
function processData(data: DataUnion): string | number | boolean {
switch (data.type) {
case 'A':
return data.value.split('').reverse().join('');
case 'B':
return data.value.reduce((acc, cur) => acc + cur, 0) / data.value.length;
case 'C':
return!data.value;
default:
const _exhaustiveCheck: never = data;
return _exhaustiveCheck;
}
}
如果新增了DataUnion
的联合类型分支,TypeScript会提示错误,因为default
分支应该永远不会执行。
2. 仔细检查类型判断条件:在编写类型判断条件时,确保与联合类型中的type
值严格匹配,避免拼写错误。可以使用常量来定义type
的值,以减少出错概率。例如:
const TYPE_A = 'A';
const TYPE_B = 'B';
const TYPE_C = 'C';
function processData(data: DataUnion): string | number | boolean {
if (data.type === TYPE_A) {
return data.value.split('').reverse().join('');
} else if (data.type === TYPE_B) {
return data.value.reduce((acc, cur) => acc + cur, 0) / data.value.length;
} else if (data.type === TYPE_C) {
return!data.value;
}
return null as any;
}