MST

星途 面试题库

面试题:TypeScript联合类型与类型守卫在泛型和条件类型中的深度运用

实现一个泛型函数`filterByType`,它接受一个数组和一个类型谓词函数作为参数。数组元素是联合类型`A | B | C`(假设`A`、`B`、`C`为不同接口类型)。类型谓词函数用于判断数组元素属于哪种类型。该函数要返回一个新数组,新数组中的元素类型由类型谓词函数决定,并且在返回类型中要精确体现出筛选后的具体类型。请详细说明类型守卫和条件类型在这个过程中的作用。
17.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
interface A {
    type: 'A';
    // 其他属性
}
interface B {
    type: 'B';
    // 其他属性
}
interface C {
    type: 'C';
    // 其他属性
}

function filterByType<T, U extends T>(array: T[], typePredicate: (element: T) => element is U): U[] {
    return array.filter(typePredicate);
}

// 示例使用
const mixedArray: (A | B | C)[] = [
    { type: 'A' },
    { type: 'B' },
    { type: 'C' }
];

const filteredArray = filterByType(mixedArray, (element): element is A => element.type === 'A');

类型守卫的作用

类型守卫是一个运行时检查,它允许我们在特定代码块中细化类型。在上述代码中,typePredicate函数就是一个类型守卫。通过element is U这种语法,TypeScript能够在filter方法内部的回调中,根据typePredicate的返回值,确定当前元素的具体类型。这样在回调内部,element就被细化为U类型,从而保证filter方法返回的数组元素类型是U类型。

条件类型的作用

在函数定义filterByType<T, U extends T>(array: T[], typePredicate: (element: T) => element is U): U[]中,并没有直接使用到条件类型。但是条件类型通常用于根据类型关系进行类型推导,在更复杂的场景下,比如当需要根据不同类型做不同处理时,条件类型可以派上用场。例如,如果要对不同类型的元素做不同的映射处理,可以利用条件类型来推导映射后的具体类型。但在这个简单的过滤场景中,类型守卫足以完成精确类型推导的任务。