2480 字
12 分钟
TypeScript 从零开始详细教程(与 JavaScript 衔接)

TypeScript 从零开始详细教程(与 JavaScript 衔接)#

前面我们学了 JavaScript 的全部基础,还做了项目。这一篇学 TypeScript(简称 TS)——它是 JavaScript 的”进化版”,目前几乎所有大型前端项目都在用。而且 Vue、React 的官方文档现在都默认用 TS 示例,学完它,你的技能就完整了。


一、TypeScript 是什么?和 JS 什么关系?#

一句话:TypeScript 是 JavaScript 的超集——在 JS 的基础上加了”类型系统”。

用一张图理解:

JavaScript 全部代码
↑ 兼容(TS 里能写 JS)
TypeScript = JavaScript + 类型

核心区别:

JavaScriptTypeScript
类型检查运行时才报错写代码时就报错
常见错误运行时才发现,可能影响用户编译时(开发时)就发现
谁在跑浏览器直接执行要先编译成 JS,再交给浏览器

TS 最大的价值:把错误挡在”写代码的时候”。

看个例子——JS 的经典坑:

// JavaScript:这段代码不会报错,但结果不对
function add(a, b) {
return a + b;
}
console.log(add(1, 2)); // 3,正常
console.log(add("1", 2)); // "12"!字符串拼接了,不是加法!

JS 不知道你想让 a、b 是数字,传字符串也”乐意”。TS 能在你传错类型时直接画红线:

// TypeScript:声明 a、b 必须是数字
function add(a: number, b: number): number {
return a + b;
}
// add("1", 2); // ❌ 编辑器立刻标红:类型"string"不能赋给"number"
console.log(add(1, 2)); // ✅ 3

类型是给开发者看的”说明书”,也是让代码更可靠的”安全网”。


二、怎么安装和运行 TypeScript?#

安装(需要 Node.js)#

Terminal window
npm install -g typescript

编译运行#

TS 文件后缀是 .ts。写好后用 tsc 编译成 .js

Terminal window
# 1. 写一个 hello.ts 文件
# 2. 编译
tsc hello.ts
# 3. 生成了 hello.js,再用 node 运行
node hello.js

每次都要编译太麻烦? 用 watch 模式,文件一保存自动编译:

Terminal window
tsc --watch hello.ts

直接在浏览器控制台试(不装也能玩)#

TypeScript 官方提供了在线练习场:访问 TypeScript Playground(tsplay.dev),左边写 TS 右边看编译后的 JS,零安装就能学。学习阶段强烈推荐先用它。


三、基础类型:给数据”贴上标签”#

TS 的写法就是在变量后面加 : 类型

原始类型#

let age: number = 18; // 数字
let price: number = 3.14; // 小数也是 number
let name: string = "小明"; // 字符串
let isDone: boolean = true; // 布尔
// null 和 undefined
let empty: null = null;
let notSet: undefined = undefined;

数组#

let numbers: number[] = [1, 2, 3]; // 数字数组
let names: string[] = ["小明", "小红"]; // 字符串数组
// 或者用泛型写法(等价)
let nums: Array<number> = [1, 2, 3];

元组(Tuple):固定长度和类型#

let person: [string, number] = ["小明", 18];
// person = [18, "小明"]; // ❌ 错误:顺序不对

any 和 unknown:特殊情况#

let anything: any = 42; // any:任何类型都行(尽量少用,会失去 TS 的保护)
anything = "字符串也可以";
let maybe: unknown = "某个未知值"; // unknown:类型未知(比 any 安全)

原则: 能用具体类型就用具体类型;any 会让 TS 失去意义,尽量别用。

类型推断:不写也能自动识别#

TS 很聪明,初始化时就能自动推断类型,不写也行:

let age = 18; // TS 自动推断 age 是 number
// age = "十八"; // ❌ 报错:不能把 string 赋给 number

建议: 简单变量靠推断,函数参数和返回值主动写清楚。


四、接口(interface):给对象”定规矩”#

对象是 JS 里最常用的数据结构。TS 用 interface 规定”对象必须长什么样”:

interface Student {
name: string;
age: number;
grade?: string; // ? 表示可选,可以没有
}
// 符合接口的对象
let s1: Student = { name: "小明", age: 18 };
let s2: Student = { name: "小红", age: 17, grade: "高二" };
// let s3: Student = { name: "小刚" };
// ❌ 报错:缺少属性 age

为什么有用? 团队协作时,接口就是”契约”:写数据的人知道要提供什么,用数据的人知道有什么字段。IDE 还会自动提示字段名,防止拼错。

接口也可以描述函数#

interface AddFn {
(a: number, b: number): number;
}
const add: AddFn = (a, b) => a + b;

接口可以被”继承”(extends)#

interface Person {
name: string;
age: number;
}
interface Employee extends Person {
company: string; // 在 Person 基础上再加字段
}
let e: Employee = { name: "张三", age: 30, company: "某公司" };

五、类型别名(type):给类型起外号#

type 可以给类型起别名,还能定义一些 interface 做不到的(比如联合类型):

// 给对象类型起别名
type Point = {
x: number;
y: number;
};
// 给联合类型起别名
type Status = "pending" | "success" | "error"; // 只能是这三个字符串之一
let s: Status = "success"; // ✅
// let s2: Status = "failed"; // ❌ 不在列表里

联合类型(Union):一个值可以是多种类型#

// id 可以是数字或字符串
function getById(id: number | string) {
console.log("查询 id:", id);
}
getById(1); // ✅
getById("abc"); // ✅

交叉类型(Intersection):合并多个类型#

type Name = { name: string };
type Age = { age: number };
type Person = Name & Age; // 两个都要有
let p: Person = { name: "小明", age: 18 }; // ✅

六、函数类型:参数和返回值都要”说清楚”#

基本写法#

// 参数类型 + 返回值类型
function greet(name: string): string {
return `你好,${name}`;
}
// 箭头函数也一样
const add = (a: number, b: number): number => a + b;

可选参数#

function register(name: string, phone?: string) {
console.log(`注册用户:${name}`);
if (phone) {
console.log(`手机号:${phone}`);
}
}
register("小明"); // ✅ 不传 phone 也行
register("小红", "13800000000"); // ✅

注意: 可选参数必须放在最后面。

默认参数#

function discount(price: number, rate: number = 0.9) {
return price * rate;
}
discount(100); // 90(用默认 0.9)
discount(100, 0.5); // 50

void:没有返回值的函数#

function log(message: string): void {
console.log(message); // 没有 return
}

七、类(class)与访问修饰符#

TS 的类在 JS 的 class 基础上加了类型和访问控制:

class Animal {
// 属性要先声明类型
name: string;
private age: number; // private:只有类内部能访问
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
speak(): void {
console.log(`${this.name} 叫了一声`);
}
getAge(): number {
return this.age;
}
}
let dog = new Animal("旺财", 3);
dog.speak(); // 旺财 叫了一声
console.log(dog.name); // ✅ 公开属性可以访问
// console.log(dog.age); // ❌ private 属性外部访问不了

修饰符速记:

  • public(默认):谁都行
  • private:只有类内部
  • protected:类内部和子类

八、泛型(Generic):写一次,多种类型通用#

泛型让你的函数/类”不写死类型”,用的时候再定。最经典的例子是数组反转:

// 不用泛型:只能处理数字
function reverseNum(arr: number[]): number[] {
return arr.slice().reverse();
}
// 用泛型:任何类型都能处理
function reverse<T>(arr: T[]): T[] {
return arr.slice().reverse();
}
reverse([1, 2, 3]); // number[],T = number
reverse(["a", "b", "c"]); // string[],T = string

<T> 里的 T 是一个”类型变量”,调用时自动推断成实际类型。好处: 一种逻辑,各种类型通用,而且类型检查不会丢。

另一个常见例子:

function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
let first = firstElement([10, 20, 30]); // first 的类型是 number

九、tsconfig.json:TS 项目的”总配置”#

真实项目里,TS 的编译配置放在 tsconfig.json 里。用命令一键生成:

Terminal window
tsc --init

生成的配置里,最常用的是这几项:

{
"compilerOptions": {
"target": "ES2020", // 编译成哪个版本的 JS
"module": "ESNext", // 模块系统
"strict": true, // 严格模式(强烈建议开启)
"outDir": "./dist", // 编译输出目录
"rootDir": "./src" // 源码目录
},
"include": ["src"] // 编译哪些目录
}

"strict": true 最重要——它开启所有严格检查(包括 null 检查),虽然刚开始会觉得”烦”,但它能拦住大量真实 bug。业界共识:新项目一定要开 strict。


十、从 JS 平滑过渡到 TS 的路线#

如果你已经把前面的 JS 教程学完,过渡到 TS 其实非常自然:

JS 写法TS 写法变化
let age = 18let age: number = 18加类型(也可靠推断不写)
function f(a, b)function f(a: number, b: number): number参数和返回值加类型
const obj = {...}interface X {...} + 类型标注用接口定义对象形状
const add = (a,b) => a+bconst add = (a: number, b: number) => a + b箭头函数加类型

三个实用技巧:

  1. 遇到报错先看类型:TS 报错信息会把原因说得很清楚(“不能把 string 赋给 number”),跟着改就行
  2. ? 处理可能为空的字段user?.name 可选的配合 ?. 可选链,避开”读不到属性”错误
  3. 不确定就用 unknown 加类型收窄:用 typeofinstanceof 判断后再操作
function process(value: unknown) {
if (typeof value === "string") {
console.log(value.toUpperCase()); // 收窄后 TS 知道它是 string
} else if (typeof value === "number") {
console.log(value + 1);
}
}

实际项目怎么用? 现在的主流做法:

  • Vue 3 项目:<script setup lang="ts">,组合式 API 天然支持类型
  • React 项目:函数组件参数用接口描述 props

十一、总结#

这一篇我们从零学完了 TypeScript:

  • TS 是 JS 的超集:加类型系统,把错误挡在开发时
  • 安装运行:tsc 编译,Playground 在线练习
  • 基础类型:number、string、boolean、数组、元组、any、unknown
  • 接口 interface:给对象”定规矩”,支持继承
  • 类型别名 type:联合类型、交叉类型
  • 函数类型:参数、返回值、可选参数、默认参数、void
  • 类与修饰符:public、private、protected
  • 泛型:写一次、多种类型通用
  • tsconfig.json:项目配置,strict 必开
  • 过渡路线:JS 写法 + 类型标注 = TS

到这里,你的前端学习主线就完整了:

JavaScript 基础 → ES6+ → 异步编程 → fetch 网络请求 → HTML/CSS 强化 → Vue/React 框架 → 项目实战 → TypeScript

接下来就是不断做项目、读源码、写代码。编程是门手艺,手艺靠练不靠看。 把教程里的每个示例都亲手敲一遍,你就真正入门了。加油!

TypeScript 从零开始详细教程(与 JavaScript 衔接)
https://021028.xyz/posts/default/73/
作者
021028
发布于
2026-08-11
许可协议
CC BY-NC-SA 4.0