MST

星途 面试题库

面试题:TypeScript类型保护与类型缩小的边界情况及优化策略

在使用TypeScript的类型保护和类型缩小时,会遇到一些边界情况,例如联合类型中有大量重叠属性,或者在递归类型中进行类型保护。请阐述你对这些边界情况的理解,以及相应的优化策略,包括如何在不影响性能的前提下,保持代码的可读性和可维护性。同时,请给出具体的代码示例来解释你的策略。
28.2万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

1. 联合类型中有大量重叠属性

  • 理解:当联合类型中存在大量重叠属性时,类型保护可能会变得复杂。因为在进行类型判断时,多个类型的重叠属性使得区分不同类型变得困难,可能导致类型保护逻辑冗长且易错。
  • 优化策略
    • 利用类型谓词:通过自定义类型谓词函数来明确区分不同类型。这样可以将复杂的类型判断逻辑封装在函数中,提高代码可读性。
    • 使用in关键字:利用in关键字来检查对象是否具有某个属性,从而缩小类型范围。
  • 代码示例
interface Dog {
    type: 'dog';
    name: string;
    bark: () => void;
}

interface Cat {
    type: 'cat';
    name: string;
    meow: () => void;
}

type Pet = Dog | Cat;

// 类型谓词函数
function isDog(pet: Pet): pet is Dog {
    return (pet as Dog).bark!== undefined;
}

function handlePet(pet: Pet) {
    if (isDog(pet)) {
        pet.bark();
    } else {
        pet.meow();
    }
}

// 使用in关键字
function handlePetWithIn(pet: Pet) {
    if ('bark' in pet) {
        pet.bark();
    } else {
        pet.meow();
    }
}

2. 递归类型中进行类型保护

  • 理解:递归类型是指类型定义中包含自身的类型,在这种类型上进行类型保护时,可能会陷入无限循环或者难以准确判断类型层次。
  • 优化策略
    • 添加终止条件:在递归类型的类型保护逻辑中,明确添加终止条件,避免无限递归。
    • 使用辅助类型:通过辅助类型来简化递归类型的判断,例如使用ExcludeExtract等工具类型。
  • 代码示例
interface TreeNode {
    value: number;
    children?: TreeNode[];
}

function sumTree(node: TreeNode): number {
    let sum = node.value;
    if (node.children) {
        for (let child of node.children) {
            sum += sumTree(child);
        }
    }
    return sum;
}

// 使用辅助类型示例
type Leaf = { type: 'leaf'; value: number };
type Branch = { type: 'branch'; value: number; children: (Leaf | Branch)[] };
type Tree = Leaf | Branch;

function sumTreeWithHelper(tree: Tree): number {
    if (tree.type === 'leaf') {
        return tree.value;
    } else {
        let sum = tree.value;
        for (let child of tree.children) {
            sum += sumTreeWithHelper(child);
        }
        return sum;
    }
}

通过上述方法,可以在处理这些边界情况时,既保证性能,又能保持代码的可读性和可维护性。