面试题答案
一键面试可能产生的类型陷阱
- 未覆盖所有条件分支:在条件类型中,可能因为遗漏某些条件分支,导致覆盖率不准确。例如:
type IsString<T> = T extends string? true : false;
function checkType<T>(arg: T): IsString<T> {
// 假设这里没有处理所有可能的类型情况
return (arg as any) === 'string' ? true : false;
}
在这个例子中,checkType
函数对 IsString
条件类型的实现可能没有覆盖所有 T
类型的情况,导致覆盖率统计有误。
2. 泛型实例化不完整:对于嵌套泛型类型,如果没有对泛型进行全面的实例化测试,会遗漏部分代码路径。比如:
type NestedGeneric<T> = { value: T };
type OuterGeneric<T> = { inner: NestedGeneric<T> };
function getNestedValue<T>(obj: OuterGeneric<T>): T {
return obj.inner.value;
}
如果只测试了部分 T
的类型,如 string
,而没有测试 number
、boolean
等其他类型,就会存在覆盖率漏洞。
3. 交叉类型的部分属性未覆盖:交叉类型合并多个类型的属性,可能只测试了部分属性,而遗漏了其他属性相关的代码。例如:
type A = { propA: string };
type B = { propB: number };
type AB = A & B;
function processAB(obj: AB) {
// 假设只处理了 propA,遗漏了 propB
console.log(obj.propA);
}
这种情况下,对于 propB
相关的代码就没有被覆盖到。
规避策略
- 编写全面的测试用例:针对条件类型,要覆盖所有可能的条件分支。
type IsString<T> = T extends string? true : false;
function checkType<T>(arg: T): IsString<T> {
return typeof arg === 'string' ? true : false;
}
// 测试用例
const isString1: IsString<string> = checkType('test');
const isString2: IsString<number> = checkType(123);
通过这样的测试用例,可以确保 checkType
函数在不同类型输入下都能正确运行,提高覆盖率。
2. 对泛型进行多种实例化测试:对于嵌套泛型类型,使用多种不同类型实例化泛型进行测试。
type NestedGeneric<T> = { value: T };
type OuterGeneric<T> = { inner: NestedGeneric<T> };
function getNestedValue<T>(obj: OuterGeneric<T>): T {
return obj.inner.value;
}
// 测试用例
const outerString: OuterGeneric<string> = { inner: { value: 'test' } };
const outerNumber: OuterGeneric<number> = { inner: { value: 123 } };
const stringValue = getNestedValue(outerString);
const numberValue = getNestedValue(outerNumber);
通过不同类型的实例化,保证 getNestedValue
函数在各种情况下的正确性和覆盖率。
3. 确保交叉类型所有属性都被测试:在处理交叉类型时,要确保所有属性相关的代码都被覆盖。
type A = { propA: string };
type B = { propB: number };
type AB = A & B;
function processAB(obj: AB) {
console.log(obj.propA);
console.log(obj.propB);
}
// 测试用例
const abObj: AB = { propA: 'test', propB: 123 };
processAB(abObj);
这样可以保证 processAB
函数中与 AB
交叉类型所有属性相关的代码都被执行,提高覆盖率和代码健壮性。