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、复杂函数、返回值,显式标注类型更安全。
相关推荐
fanruitian7 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo7 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk7 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
2501_944525548 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
李白你好9 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说10 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
徐同保11 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
刘一说11 小时前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js
一周七喜h12 小时前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
weixin_3954489112 小时前
main.c_cursor_0202
前端·网络·算法