MST

星途 面试题库

面试题:复杂类型结构下 TypeScript 的类型兼容性与类型推断

在 TypeScript 中,考虑一个深度嵌套的对象类型结构,如 `type DeepObject = { a: { b: { c: number } } }` 和 `type ShallowObject = { a: { b: number } }`。写一个函数,使其接受 `DeepObject` 类型参数,但在函数内部将其作为 `ShallowObject` 类型使用,探讨类型兼容性和类型推断在此场景下是如何协同工作的,以及可能出现的问题及解决方法。
17.0万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

代码实现

function transformObject(obj: DeepObject): void {
    // 这里将DeepObject类型的obj当作ShallowObject类型来使用
    const shallowObj: ShallowObject = {
        a: {
            b: obj.a.b.c
        }
    };
    console.log(shallowObj);
}

类型兼容性和类型推断分析

  1. 类型兼容性:在TypeScript中,对象类型之间的兼容性是基于结构的。如果一个类型的结构包含另一个类型的所有属性,那么前者兼容后者。在这个场景中,DeepObject 包含了 ShallowObject 中的所有属性结构,所以从结构上 DeepObject 是兼容 ShallowObject 的。
  2. 类型推断:TypeScript 的类型推断会根据变量的赋值和函数参数的类型来推断变量的类型。在函数 transformObject 中,参数 obj 被明确指定为 DeepObject 类型,而在创建 shallowObj 时,TypeScript 能够根据对象字面量的结构推断出 shallowObj 的类型为 ShallowObject

可能出现的问题及解决方法

  1. 问题:如果 DeepObject 的结构发生变化,例如 type DeepObject = { a: { b: { d: number } } },那么 transformObject 函数内部的赋值会出错,因为 obj.a.b.c 不存在了。
  2. 解决方法
    • 可选链操作符:在访问深层属性时使用可选链操作符,如 const shallowObj: ShallowObject = { a: { b: obj.a?.b?.c?? 0 } };,这样即使深层属性不存在,也不会抛出错误,而是使用默认值。
    • 类型守卫:在函数内部添加类型守卫来确保 DeepObject 具有预期的结构,例如:
function transformObject(obj: DeepObject): void {
    if (obj.a && obj.a.b && 'c' in obj.a.b) {
        const shallowObj: ShallowObject = {
            a: {
                b: obj.a.b.c
            }
        };
        console.log(shallowObj);
    } else {
        console.error('Unexpected object structure');
    }
}