百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

前端人速存!10 个 TypeScript 实战技巧让代码会 “说话”

liuian 2025-05-11 17:05 5 浏览

在React、Vue这些前端框架你追我赶卷性能的当下,TypeScript早已悄悄成为众多项目的 “幕后英雄”。但说实话,不少兄弟在和它打交道时,都被类型报错折磨得够呛 —— 明明代码逻辑没问题,为啥就是通不过编译?别急!今天就掏出 10 个压箱底的实战技巧,手把手教你驯服这个 “代码质检员”!

让类型自己 “开口报身份”:字面量类型的魔法

你可能会发现,写代码时经常遇到某个变量只能取固定值的情况。举个例子,订单状态只有 “待支付”“已发货”“已完成” 三种,要是用普通字符串类型,一不小心就可能传进个 “已取消” 导致逻辑错乱。这时候,字面量类型就派上用场了!

// 定义订单状态的字面量类型,明确限定取值范围
type OrderStatus = '待支付' | '已发货' | '已完成';
// 声明订单对象,status属性只能是上述三种值
const order = {
id: 1,
status: '待支付' as OrderStatus
};
// 尝试赋值非法状态会直接报错!
// order.status = '已取消'; // 编译时就会报错

是不是很神奇?通过这种方式,代码自己就能 “告诉” 你哪些值是合法的,提前拦截掉一大波潜在 Bug。

泛型:代码界的 “万能模板”

泛型这玩意儿,初次接触确实有点抽象,但掌握了它,你会发现写代码就像开了挂!想象你要写个函数,既能处理数字数组求和,又能处理字符串数组拼接,要是不用泛型,可能得写两个函数 —— 太麻烦了!

// 定义一个通用函数,T代表待确定的类型
function handleArray<T>(arr: T[]): T[] {
// 这里可以对数组进行各种操作,比如反转
return arr.reverse();
}
const numArr = [1, 2, 3];
const strArr = ['a', 'b', 'c'];
// 调用函数时,TypeScript会根据传入的参数自动推导类型
const reversedNumArr = handleArray(numArr);
const reversedStrArr = handleArray(strArr);

为什么这个方法有效?关键在于泛型允许你先 “占位”,等实际调用时再确定具体类型。就像拿着空白模板,不管是数字、字符串还是自定义对象,都能往里套!

接口 VS 类型别名:选对工具事半功倍

这俩兄弟经常让新手犯迷糊 —— 到底啥时候用接口,啥时候用类型别名?去年我们团队遇到一个典型案例:开发电商后台时,需要定义用户信息,一开始用类型别名快速搞定。结果后期要给管理员用户扩展权限字段,类型别名就显得力不从心了。

// 用接口定义基础用户类型
interface User {
name: string;
age: number;
}
// 扩展接口,定义管理员用户类型
interface AdminUser extends User {
role: 'admin';
permissions: string[];
}
// 类型别名定义简单联合类型
type StringOrNumber = string | number;

要特别警惕的是:如果需要继承、扩展,优先选接口;只是组合已有类型,类型别名更轻便。

类型断言:和 TypeScript 的 “私下约定”

有时候你心里清楚某个变量的真实类型,但 TypeScript 就是 “认死理” 不给通过。这时候就需要类型断言,和它来个 “私下约定”。

// 获取DOM元素,TypeScript默认认为是HTMLElement类型
const element = document.getElementById('myButton');
// 通过类型断言,告诉TypeScript这是个HTMLButtonElement
const button = element as HTMLButtonElement;
button.addEventListener('click', () => {
console.log('按钮被点击');
});

不过得悠着点用!毕竟这相当于跳过了类型检查,如果判断错误,运行时可能会出大问题。

交叉类型:合并类型的 “超级胶水”

想象你要开发一个既具备用户属性,又有管理员权限的 “超级用户” 类型,该怎么办?交叉类型就是答案!

// 定义用户类型
interface RegularUser {
name: string;
age: number;
}
// 定义管理员类型
interface Admin {
role: 'admin';
permissions: string[];
}
// 使用交叉类型合并两个类型
type SuperUser = RegularUser & Admin;
const superUser: SuperUser = {
name: 'adminUser',
age: 30,
role: 'admin',
permissions: ['create', 'delete']
};

令人惊讶的是,通过交叉类型,你能快速组合多个类型的特性,让代码结构更清晰。

可选链操作符:防 “undefined” 的终极武器

在处理多层嵌套对象时,最怕某个属性突然 “消失” 导致报错。举个例子,获取用户地址的门牌号,如果用户没填地址,直接访问user.address.houseNumber就会引发TypeError。

interface User {
name: string;
address?: {
street: string;
houseNumber?: number;
};
}
const user: User = {
name: 'test',
address: {
street: '123 Road'
}
};
// 使用可选链操作符,安全获取门牌号,不存在时返回undefined
const houseNumber = user.address?.houseNumber;
console.log(houseNumber);

这就涉及到一个关键点:可选链操作符会在属性不存在时自动 “短路”,避免深层访问报错,堪称处理不确定数据的必备神器!

函数重载:让函数 “见人说人话”

有时候一个函数需要根据不同参数类型,返回不同类型的值。比如一个parse函数,传入字符串时解析成对象,传入对象时直接返回。

// 声明函数重载签名,定义不同参数和返回值类型
function parse(data: string): object;
function parse(data: object): object;
// 实现函数,根据传入参数类型处理逻辑
function parse(data: string | object): object {
if (typeof data ==='string') {
return JSON.parse(data);
}
return data;
}
const str = '{"name": "test"}';
const obj = { name: 'test' };
const result1 = parse(str);
const result2 = parse(obj);

经过验证的最佳实践是:通过函数重载,能让函数在不同场景下表现得更 “智能”,同时保留清晰的类型定义。


索引签名:动态属性的 “安全网”

开发配置项管理功能时,经常遇到属性名不固定的情况。要是用普通接口定义,新增属性就会报错。

// 定义包含索引签名的接口,允许任意字符串属性名
interface Config {
[key: string]: string | number;
}
const config: Config = {
name: 'app',
version: 1.0
};
// 动态添加属性也不会报错
config.env = 'production';

有了索引签名,就像给对象装了个 “弹性容器”,既能限制属性值类型,又能灵活扩展属性。

条件类型:类型界的 “智能开关”

在处理数据转换时,经常需要根据不同条件生成不同类型。比如将数组中的元素类型转换为可选类型。

// 定义条件类型,T为传入类型
type MakeOptional<T> = {
[P in keyof T]?: T[P];
};
interface Person {
name: string;
age: number;
}
// 使用条件类型,将Person类型转换为所有属性可选
type OptionalPerson = MakeOptional<Person>;
const optionalPerson: OptionalPerson = {};

为啥它这么好用?因为条件类型能在类型层面做逻辑判断,实现动态类型转换,大大提升代码的灵活性。

命名空间:代码的 “收纳大师”

项目大了之后,各种类型定义、函数声明混在一起,找起来特别费劲。这时候命名空间就像个 “收纳盒”,把相关代码规整得明明白白。

// 定义命名空间,存放用户相关代码
namespace UserModule {
export interface User {
name: string;
age: number;
}
export function getUser(): User {
return { name: 'test', age: 30 };
}
}
// 使用命名空间中的类型和函数
const user: UserModule.User = UserModule.getUser();

必须强调的是:合理使用命名空间,能有效避免命名冲突,让项目结构更清晰,维护起来也更轻松!

掌握这 10 个技巧,TypeScript基本就能被你拿捏得死死的!不过话说回来,有的开发者觉得类型检查太严格,影响开发效率;也有人认为严格类型才是代码质量的保障。你在项目里是更倾向 “严格模式”,还是喜欢 “适度宽松” 呢?欢迎在评论区聊聊你的实战经验!

相关推荐

HR必备Excel函数:4个与日期相关的计算函数。

提到日期函数,很多人首先会想到“today”,它可以显示当天的日期,并且每次打开表格时都会自动更新。但是,对于前天、昨天、明天和后天的日期,就不能用yesterday或者tomorrow等这些英文了,...

这篇文章有点长,但可以让你十分钟玩转Excel的时间函数

日期与时间函数——TODAY、NOW、YEAR、MONTH、DAY!如何用WORKDAY函数查询距离某天的第20个工作日是哪一天?如何用NETWORKDAYS函数查询员工工作了多少个工作日?如何用WE...

Excel2020年日历套装,表格设计,农历显示,查阅套打轻松应用

Hello大家好,我是帮帮。今天跟大家分享一组Excel2020年日历套装,表格设计,自带农历控件,查阅套打轻松应用。有个好消息!为了方便大家更快的掌握技巧,寻找捷径。请大家点击文章末尾的“了解更多”...

巧用NETWORKDAYS函数计算两个日期之间工作日的天数

带有日期的单元格是我们日常使用EXCEL的时候经常见到的,有的时候我们需要求出两个日期之间间隔的天数,可以直接用结束日期减去开始日期即可,这是个非常简单的减法公式。不过这个单纯的减法公式会默认去掉开始...

Excel按工作日、休息日进行汇总

1、按周六日/其它时间汇总为了区分一周的周六日和其它时间,可以使用WEEKDAY函数,把WEEKDAY函数的第2个参数指定为2,如WEEKDAY(A3,2),则周一返回1,周二返回2,…,周六返回...

如何计算每月应出勤天数,如有法定假期和调休,如何计算

本文介绍如何计算每月的应出勤天数。第一部分介绍正常双休制下计算应出勤天数;第二部份介绍当月有法定假期和调休的情况下计算应出勤天数。一、计算正常双休制的应出勤天数如下图所示,要求计算各员工2021年3月...

《Excel一键生成工作日历:让会议排期更轻松!》

每当需要安排会议时,总要翻看日历确认工作日,再逐个标注会议时间,既耗时又容易出错。今天教大家用Excel快速生成工作日历表,让会议排期变得简单高效!一、快速生成日历框架创建基础日期:在A1单元格输入月...

如何计算指定日期区间内,有多少工作日和休息日?

大家好,今天咱们要解决的问题是如何计算给定的一段日期内,正常工作日有多少天,放假时间有多少天?比如咱们要计算2025年3月份工作日一共有多少天,又有多少天放假,如下图所示:通过肉眼我们可以数清楚,20...

如何如何在表格中自动突出显示双休日?

现在不少人喜欢用Excel来制作备忘录或安排工作事项。在表格中输入日期后,可以使用条件格式突出显示双休日,避免在休息日安排了工作。具体方法是这样的:第1步:选择要设置条件格式的日期单元格区域;在“开始...

excel函数技巧:networkdays.intl判断节假日

如图,想知道6月的每一天是否是节假日,公式如下:=NETWORKDAYS.INTL(A2,A2,1,$E$2:$E$28)这个函数既可以判断当前日期(一参=二参)是否是周末及工作日(三参、四参)还可得...

仅需3步,让考勤表根据实际休息日,自动地填充颜色

Hello,大家好,之前跟大家分享了我们如何让考勤表根据单休与双休自动的填充颜色,最近有粉丝问到:能不能让考勤表根据实际的休息日自动的填充颜色呢?可以是可以,只不过因为牵扯到假期调休,我们每年的休息日...

5步搞定动态考勤表!标记节假日、调休日?Excel自动变色!

今天教你用「动态考勤表」一招解决所有问题!只需输入月份,自动变色、自动更新节假日,从此告别加班,效率翻倍!动态考勤表的优势:自动变色:节假日、双休日一键标记,颜色分明。一表多用:修改月份即可...

一起用python做个炫酷音乐播放器,想听啥随便搜

前言前段时间写的Python自制一款炫酷音乐播放器,有不少小伙伴私信我,对播放器提了不少改进建议,让我完善播放器的功能。今天音乐播放器2.0版本完成了,大家一起来看看是如何用python自制一款炫酷的...

用Python做个“冰墩墩雪容融”桌面部件(好玩又有趣)

桌面太单调?今天就带大家,一起用Python的PyQt5开发一个有趣的自定义桌面动画挂件,看看实现的动画挂件效果!下面,我们开始介绍这个自定义桌面动画挂件的制作过程。一、核心功能设计实现将动态图gif...

Python串口调试助手源码分享

以下是一个基于Python和PyQt5实现的串口调试助手示例,包含核心功能实现代码:pythonimportsysimportserialfromPyQt5.QtCoreimportQTim...