ts的类型推论

typescript的类型推论(Type Inference)是指在没有显式标注类型的情况下,编译器自动根据代码的上下文推断出变量、参数、返回值等的类型。这是ts能在保持类型安全的同时减少冗余代码的关键特性。

1.基于初始化的变量推论

当我声明变量并初始化时,Ts就会根据初始值来判断类型。

ts 复制代码
let name = "Alice"; // 推论为 string
let age = 25; // 推论为 number
let isActive = true; // 推论为 boolean
let items = [1, 2, 3]; // 推论为 number[]
let mixed = [1, "a", true]; // 推论为 (number | string | boolean)[]

一旦推断完成,就不能赋值为其他类型了哈。

比如: name =123 错哈 这个是错的 它是不能将number赋值给string哈~

2.函数返回值推论

函数的返回类型如果没有显式标注,Ts会根据return语句推断。

ts 复制代码
function add(a: number, b: number) {
    return a + b; // 推论返回类型为 number
}

function getName() {
    return "Bob"; // 推论返回类型为 string
}

function getPerson() {
    return {
        name: "Charlie",
        age: 30
    }; // 推论返回一个 { name: string; age: number } 对象
}
3.参数类型推论(在上下文中)

在函数调用或赋值时,Ts会根据上下文推断参数类型。

ts 复制代码
// 数组的 map 方法
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
// TS 知道 numbers 是 number[],所以 map 的参数 n 被推论为 number
ts 复制代码
// 回调函数
document.addEventListener("click", (e) => {
    console.log(e.target); // e 被推论为 MouseEvent
});
4.最佳通用类型(Best Common Type)

当表达式中存在多个类型时,Ts会尝试找到一个"最合适的"公共类型。

ts 复制代码
let arr = [1, "hello", false];
// 推论为 (number | string | boolean)[] ------ 联合类型

let arr2 = [null, "hello"];
// 推论为 (string | null)[]

let arr3 = [0, 1, null];
// 推论为 (number | null)[]

在某些情况下,TS会忽略null或undefined,如果其他类型更"具体"。

ts 复制代码
let arr4 = [1, 2, 3, null]; // 仍可能推论为 number[](取决于 strictNullChecks)
5.上下文类型(Contextual typing)

TS会根据变量被使用的"位置"来推断其类型。

ts 复制代码
window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.button); // mouseEvent 被推论为 MouseEvent
};

// 函数参数
type Handler = (e: Event) => void;
const handler: Handler = (e) => {
    // e 自动被推论为 Event 类型
    console.log(e.timeStamp);
};
6.结构化类型推论(基于形状)

TS是"结构化类型系统",会根据对象的结构推断类型。

ts 复制代码
const point = {
    x: 10,
    y: 20
};
// 推论为 { x: number; y: number }

function printPoint(p) {
    console.log(`${p.x}, ${p.y}`);
}
// p 的类型在调用时根据传入对象的结构决定
printPoint(point); // OK
printPoint({ x: 5, y: 6 }); // OK
7.泛型中的类型推论

在调用泛型函数时,TS通常能自动推断泛型类型。

ts 复制代码
function identity<T>(arg: T): T {
    return arg;
}

const result = identity("hello");
// T 被推论为 string,result 类型为 string

function reverse<T>(items: T[]): T[] {
    return items.slice().reverse();
}

const reversed = reverse([1, 2, 3]);
// T 被推论为 number,reversed 类型为 number[]
8.解构赋值推论
ts 复制代码
const user = { name: "Alice", age: 30 };
const { name, age } = user;
// name 推论为 string,age 推论为 number

const [first, second] = [1, 2];
// first, second 推论为 number

类型推论的局限性

  • 不能推论 any 的情况:如果 TS 无法确定类型,可能会推论为 any(尤其是在 --noImplicitAny 关闭时)。
  • 复杂逻辑可能推论不准确:例如条件分支中类型可能变宽。
  • 建议显式标注:对于公共 API、复杂函数、返回值,显式标注类型更安全。
相关推荐
再学一点就睡1 小时前
深入理解 Redux:从手写核心到现代实践(附 RTK 衔接)
前端·redux
天天进步20152 小时前
从零到一:现代化充电桩App的React前端参考
前端·react.js·前端框架
柯南二号3 小时前
【大前端】React Native Flex 布局详解
前端·react native·react.js
龙在天3 小时前
npm run dev 做了什么❓小白也能看懂
前端
hellokai4 小时前
React Native新架构源码分析
android·前端·react native
li理4 小时前
鸿蒙应用开发完全指南:深度解析UIAbility、页面与导航的生命周期
前端·harmonyos
去伪存真4 小时前
因为rolldown-vite比vite打包速度快, 所以必须把rolldown-vite在项目中用起来🤺
前端
KubeSphere4 小时前
Kubernetes v1.34 重磅发布:调度更快,安全更强,AI 资源管理全面进化
前端
wifi歪f5 小时前
🎉 Stenciljs,一个Web Components框架新体验
前端·javascript
1024小神5 小时前
如何快速copy复制一个网站,或是将网站本地静态化访问
前端