TypeScript 基本类型
TypeScript 基本类型 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。
学习目标
TypeScript(TS,在 JavaScript 基础上加静态类型的语言,写代码时就能查出类型错误)这一课从「给数据画像」开始:为课程、学习记录和表单定义类型。读完你应该会用 interface/type 描述数据结构,会修可空值与联合类型的报错,并明白为什么不用 any(放弃类型检查的「任意类型」)掩盖问题。
问题场景
课程对象在三个文件里出现:列表页把 c.title 手滑写成 c.titel;详情页对可能为 null 的 c.price 直接调 toFixed(2);报名脚本把 c.hours 写成了字符串。JavaScript 对此全部沉默,直到用户点开那一刻才炸。TS 的价值就在这一步:这些错误在编辑器里画红线,运行之前就拦下。
核心解释
用类型描述数据的样子:
interface Course {
id: number;
title: string;
track: 'foundation' | 'react' | 'nextjs'; // 联合类型:只能是这几个值之一
price: number | null; // 可空:要么数字,要么 null
tags?: string[]; // ? 是可选属性,可能不存在
}
const c: Course = {
id: 1,
title: '网页基础',
track: 'foundation',
price: null, // 合法:但使用前必须处理 null
};
关键规则:可空的值,用之前必须收窄(narrowing,通过判断让类型变具体)。直接写 c.price.toFixed(2) 会报错,因为 price 可能是 null:
function formatPrice(price: number | null): string {
if (price === null) return '免费';
return '¥' + price.toFixed(2); // 走过 if,TS 知道这里一定不是 null
}
any 和 unknown 都「什么类型都接受」,但 any 会关掉后续所有检查(方法名打错也不报);unknown 仍然要求你先判断再用。原则:接口边界用 unknown 接住,内部尽快收窄,永远不用 any 兜底。
示例拆解
一个真实流程:读表单输入(类型宽泛)→ 收窄 → 校验 → 使用:
function submitSurvey(raw: FormDataEntryValue | null): string {
if (typeof raw !== 'string') return '请输入内容'; // 收窄为 string
const hours = Number(raw);
if (Number.isNaN(hours)) return '请输入数字';
return `每天学习 ${hours} 小时`;
}
submitSurvey('3'); // '每天学习 3 小时'
submitSurvey(null); // '请输入内容'
FormDataEntryValue本身是File | string的联合,一层typeof判断后,后面代码里 raw 就是 string——不写断言,让判断替你说话。- 类型标注是「文档 + 检查」双重身份:
price: number | null比注释「可能为空」可靠得多,因为编译器会强制每个使用点处理。 - 验证方式:故意把
formatPrice(c.price)改成c.price.toFixed(2),确认编辑器立刻标红——这就是 TS 在替你跑测试。
动手任务
打开本课实验区:
- 给 Course 增加
hours: number,然后故意写c.hours = '8',读报错信息并用自己的话写在注释里。 - 写
totalCost(courses: Course[]): number:免费课(price 为 null)按 0 计,返回总和——不许用 any,也不许用!非空断言。 - 把实验区里用 any 掩盖的旧代码改成 unknown,按编译器提示补上收窄,修掉那个
'81'的输出。
常见错误
- 用 any 让红线消失:错误只是被藏起来,运行时照炸;类型报错要修类型,不是关检查。
- 可选属性与可空混淆:
tags?: string[]的值可能是 undefined,访问前同样要判断;price: number | null则必须显式处理 null。 - 非空断言滥用:
c.price!.toFixed(2)是「我保证不是 null」的赌注,赌输就是运行时崩溃;能用 if 收窄就不要!。 - 以为 TS 会拦截运行时的脏数据:类型只在编译期检查,接口返回的非法数据照样进来;fetch 之后的边界要自己校验(F10、F12 展开)。
检查与复盘
完成下方检查题确认理解。自查清单:
- 能说清
?:、| null、any、unknown 四者的区别 - 处理可空值的默认动作是收窄或默认值,而不是断言
- 知道类型检查管不到运行时数据,接口边界要另行校验
参考资料
- TypeScript 官方手册:日常类型 —— 接口、联合、可空的基础
- TypeScript 官方手册:类型收窄 —— 判断如何让类型变具体
- TypeScript:给 JS 程序员的 5 分钟入门 —— 从 JS 视角理解 TS
读完这一课了?
标记完成后,工作台会安排接下来的学习。