学径XUEJING · 个人学习平台通知设置

课程库 TypeScript TypeScript 起步 › 第 2

基础类型与类型推断 —— 能不写就不写的智慧

普通课50 分钟

本课导读

上一课你见识了类型标注的拦截力,一个自然的担心随之而来:"难道每个变量都要写冒号?代码不得啰嗦死?"——好消息:不用。TS 的杀手锏叫类型推断:绝大多数时候你正常写代码,编译器自己算出类型。本课盘点三大基础类型和数组,然后学会那条重要的分寸:"能让编译器推断的就不写,该写的地方绝不省"。预计 50 分钟。

三大基础类型

TS 的原始类型和 JS 完全一致,先认全写法:

TypeScript

三个要点:

  • string/number/boolean 全小写——大写的 String 是另一个东西(历史包袱),永远用小写
  • number 不分整数浮点:59959.9 都是 number(和 Python 的 int/float 分家不同)
  • 冒号语法固定:变量名: 类型 = 值——但下一节你会发现,这三行的冒号全都可以删

类型推断:编译器替你写类型

把上面代码的类型标注全部删掉,TS 照样知道一切:

TypeScript

规则一句话:初始化时赋了什么值,类型就定为什么= 599 即 number,从此这个变量的类型合同就签了——后面想塞字符串、调不存在的方法,照拦不误。推断出的类型和手写的类型,保护力完全一样

提示

类比记忆:类型推断像入职自动建档——你不用填表申报"我是工程师",HR 看你干的活(初始值)就把档案建好了;之后有人给你安排洗碗的活(赋字符串),系统照样拦。省掉的是填表,省不掉的是档案。

那什么时候必须手写类型?记住主要的两处:

TypeScript
  • 函数参数必写(推断无从下手——这也正是上一课惨案的拦截点)
  • 先声明后赋值要写(let winner: string; 声明时没有初始值)
  • 函数返回值类型通常可推断(写不写看团队习惯;本课程在"给别人用的函数"上写,练手代码不写)

这就是"能不写就不写的智慧"的完整版:局部变量交给推断,边界(函数签名)写清楚——边界是合同,合同要白纸黑字。

数组:类型 + 方括号

数组的类型 = 元素类型加一对方括号,推断同样全程在线:

TypeScript

要点两条:number[] 读作"number 的数组";空数组必须标注const cart: number[] = [])——没有初始元素,推断没有原料,这是"先声明后赋值"规则的数组版。

字符串拼接的正经写法:模板字符串

一直用 + 拼字符串有点原始。JS/TS 的正宗写法是模板字符串——反引号包裹、${} 里放表达式:

const name = "机械键盘";
const price = 599;

const msg = `${name} 售价 ${price} 元,折后 ${price * 0.8} 元`;
console.log(msg);

说明

一个诚实的说明:课程页的交互代码块暂不支持反引号语法(与页面渲染冲突),所以课内演示用 + 拼接;但你在本地 VS Code / 真实项目里请优先用模板字符串——上面这个围栏示例可以复制到本地跑。语法本身五分钟就熟:反引号 + ${表达式}

✍️ 练习

练习 1:该写不该写

四个声明,判断每处冒号标注是"必要"还是"冗余可删",把冗余的删掉验证行为不变。

TypeScript
✅ 参考答案
const city = "上海";                 // ① 冗余:有初始值,推断即可
let score: number;                   // ② 必要:先声明后赋值
score = 92;
const visits = [820, 930];           // ③ 冗余:元素在,推断出 number[]
const wishlist: string[] = [];       // ④ 必要:空数组是推断盲区

console.log(city, score, visits.length, wishlist.length);

口诀复核:有初始值交给推断(①③),没有原料必须手写(②④)。

练习 2:抓违约

下面代码有两处"违反类型合同"的操作。先预测报错位置和原因,再运行验证、修复(修复=改成类型正确的写法,不是删标注)。

TypeScript
✅ 参考答案
const stock = 12;
const labels = ["热销", "现货"];

const newStock = stock - 3;           // 数字就用数字
labels.push("2026新品");              // string[] 收字符串

console.log(newStock, labels);

两处都是推断在保护你:stock 建档为 number、labels 建档为 string[]——没写一个冒号,合同照样生效。

练习 3:库存播报函数(挑战)

写函数 report(name, stock):name 是字符串、stock 是数字,返回 "键盘:库存 12 件" 这样的播报(用 + 拼接);stock 为 0 时返回 "键盘:已售罄"。类型标注按本课的分寸来——该写的写,能省的省

TypeScript
✅ 参考答案
function report(name: string, stock: number): string {
    if (stock === 0) {
        return name + ":已售罄";
    }
    return name + ":库存 " + stock + " 件";
}

console.log(report("键盘", 12));
console.log(report("鼠标", 0));

分寸复核:参数类型必写(边界即合同);返回类型这里写了 string——它是"给别人用的函数",签名即文档。函数体内没有一个多余的冒号。

📝 随堂测验

随堂测验0 / 5 题正确

1. const price = 599 没写任何类型,price 的保护力如何?

2. 哪个场景必须手写类型标注?

3. const cart = [] 然后 cart.push(599),为什么建议写成 const cart: number[] = []?

4. TS 里 number 类型涵盖什么?

5. “能不写就不写的智慧”的完整表述是?

本课小结

  • 三大基础类型 string / number / boolean(全小写;number 不分整浮);数组 类型[]
  • 类型推断:初始化即建档,保护力与手写等同——局部变量放心不写
  • 必写两场景:函数参数(边界即合同)、先声明后赋值(含空数组)
  • 模板字符串是拼接正道(本地用反引号 + ${};课内代码块暂用 + 号)

下一课深入函数:返回值、void、可选参数与默认值——把"边界即合同"写得更讲究。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…