TypeScript 核心知识点极速梳理,新手一篇吃透
如今前端工程化开发早已离不开 TypeScript。JavaScript 作为弱类型语言,在大型项目中很容易出现类型混乱、隐性报错、代码可读性低、维护成本高等问题,而 TypeScript 是 JavaScript 的超集,在 JS 基础上增加了强大的强类型系统,从编码阶段就约束数据类型,提前规避线上 bug。
本文结合实战代码案例,系统性梳理 TypeScript 全套核心基础知识点,从基础类型、语法到抽象类、接口、泛型逐一讲解,不管是入门学习还是查漏补缺都非常合适。
一、基础开篇:类型声明 & 类型推断
TypeScript 最核心的能力就是类型约束,而类型声明和类型推断是最基础的两个语法。
1. 类型声明
我们可以主动为变量、函数参数、函数返回值指定明确类型,一旦指定,就只能存储对应类型的数据,赋值其他类型会直接抛出语法警告。
变量类型声明
typescript
运行
// 语法:变量名: 类型
let a: string; // 只能存储字符串
let b: number; // 只能存储数字
let c: boolean; // 只能存储布尔值
a = 'hello';
// a = 100; // 报错:不能将类型“number”分配给类型“string”
b = 666;
// b = '你好'; // 报错:不能将类型“string”分配给类型“number”
c = true;
// c = 666; // 报错:不能将类型“number”分配给类型“boolean”
函数类型声明
可以约束函数入参类型和返回值类型,同时也会校验参数个数:
typescript
运行
// x、y 必须是数字,函数返回值也必须是数字
function demo(x: number, y: number): number {
return x + y;
}
demo(100, 200);
// demo(100, '200'); // 报错:参数类型不匹配
// demo(100); // 报错:参数数量不足
// demo(100,200,300); // 报错:参数数量过多
2. 类型推断
如果我们没有手动指定类型,TypeScript 会自动根据初始值推断出变量类型,推断完成后,变量依然受类型约束:
typescript
运行
let d = -99; // TS自动推断 d: number
// d = false; // 报错:不能将类型“boolean”分配给类型“number”
二、TypeScript 数据类型总览
TypeScript 完全兼容 JavaScript 所有原生类型,同时新增了多款专属类型,还支持自定义类型。
1. JavaScript 原生类型
string、number、boolean、null、undefined、bigint、symbol、object
补充:
object包含数组、函数、Date 等引用类型;日常开发极少使用Number/String/Boolean包装构造函数。
2. TypeScript 新增类型
void、never、unknown、any、enum(枚举)、tuple(元组)
3. TS 自定义类型
通过 type、interface 自定义复杂类型,满足业务个性化约束。
基础类型对照表
表格
| 类型 | 描述 | 示例 |
|---|---|---|
| number | 数字类型 | 1、-33、2.5 |
| string | 字符串类型 | 'hello'、' 你好' |
| boolean | 布尔类型 | true、false |
| 字面量 | 固定唯一值 | ' 男 '、100 |
| any | 任意类型(关闭类型校验) | 任意数据 |
| unknown | 安全的任意类型 | 任意数据 |
| never | 无有效值 | 无 |
| void | 空值 /undefined | 无返回值函数 |
| object | 非原始引用类型 | {name: ' 张三 '} |
| tuple | 定长、定类型数组 | [string, number] |
| enum | 枚举类型 | 状态、选项集合 |
三、常用内置类型深度解析
这部分是 TS 日常开发使用频率最高的内容,逐个拆解用法、特性和注意事项。
3.1 字面量类型
字面量类型会强制变量只能等于指定的固定值,结合|还能实现联合字面量,常用于限定选项、状态。
typescript
运行
// 1. 基础字面量:只能赋值 "你好"
let a: '你好';
a = '你好';
// a = '欢迎'; // 报错:类型不匹配
// 2. 数字字面量:只能赋值 100
let b: 100;
b = 100;
// b = 200; // 报错
// 3. 联合字面量(常用):性别只能是 男 / 女
let gender: '男' | '女';
gender = '男';
gender = '女';
// gender = '未知'; // 报错
3.2 any 任意类型
any 表示放弃类型检查,变量可以赋值任意类型数据,分为显式 any 和隐式 any。
⚠️ 注意:项目中尽量少用 any,会丧失 TS 类型保护的意义。
typescript
运行
// 显式 any:手动指定类型
let a: any;
a = 100;
a = '你好';
a = false;
// 隐式 any:未指定类型、无初始值,TS自动推断为 any
let b;
b = 100;
b = '你好';
// 特性:any 类型变量可以赋值给任意类型变量
let x: string;
x = a; // 无报错
3.3 unknown 未知类型
unknown 被称为类型安全的 any,同样可以接收任意类型数据,但不会关闭类型校验,是推荐的「未知数据」解决方案。
核心特性:
- 可以接收任意类型赋值;
- 不能直接赋值给其他明确类型;
- 不能直接调用属性 / 方法。
typescript
运行
let a: unknown;
a = 100;
a = '你好';
let x: string;
// x = a; // 报错:不能将 unknown 赋值给 string
// 三种合法赋值方式
// 方式1:类型判断(推荐,类型守卫)
if (typeof a === 'string') {
x = a;
}
// 方式2:类型断言 写法一
x = a as string;
// 方式3:类型断言 写法二(JSX环境不推荐)
x = <string>a;
// 调用方法限制
let str3: unknown = 'hello';
// str3.toUpperCase(); // 报错:unknown 无法直接调用方法
(str3 as string).toUpperCase(); // 断言后正常使用
3.4 never 类型
never 表示不存在任何有效值,undefined、null、0、空字符串都不允许赋值。
使用场景:
- 几乎不用
never定义普通变量(无实际意义); - TS 自动推断逻辑永远走不到的代码块;
- 约束抛出异常、死循环的函数返回值。
typescript
运行
// 1. 定义 never 变量:所有赋值都会报错
let a: never;
// a = 1;
// a = undefined;
// 2. 函数抛出异常,返回值指定为 never
function demo(): never {
throw new Error('程序异常退出');
}
3.5 void 类型
void 表示无返回值,等价于 undefined,严格模式下不允许赋值 null,绝大多数场景用于约束函数返回值。
typescript
运行
let a: void = undefined;
// let b: void = null; // 严格模式下报错
// 无返回值函数,推荐使用 void
function demo1(): void {}
function demo2(): void { return; }
function demo3(): void { return undefined; }
// function demo4(): void { return 666; } // 报错:返回值类型不匹配
3.6 object 类型
区分 object 和 Object,是新手高频踩坑点:
object:代表非原始类型(对象、数组、函数),原始类型(字符串、数字、布尔、null、undefined)均不允许赋值;Object:代表 Object 包装实例,范围极广,开发中几乎不用。
typescript
运行
let a: object;
// 合法:非原始类型
a = {};
a = [1, 2, 3];
a = function(){};
// 报错:原始类型
// a = 1;
// a = '你好';
// a = null;
实际开发的精准类型写法
日常不会单纯使用 object,而是精准定义对象、数组、函数结构:
typescript
运行
// 1. 定义普通对象(? 代表可选属性)
let person: { name: string; age?: number };
person = { name: '张三', age: 18 };
person = { name: '李四' };
// 2. 允许额外属性的对象
let car: { price: number; color: string; [k: string]: any };
car = { price: 100, color: '红色', brand: '华为' };
// 3. 定义数组
let arr1: string[]; // 等价于 Array<string>
arr1 = ['a', 'b', 'c'];
// 4. 定义函数类型
let fn: (a: number, b: number) => number;
fn = (x, y) => x + y;
3.7 tuple 元组
元组(tuple)是固定长度、固定位置类型的特殊数组,区别于普通数组,对每一个位置的类型都有严格约束。
typescript
运行
// 规定:数组第1项为字符串,第2项为数字,长度必须为2
let t: [string, number];
t = ['hello', 123];
// t = ['hello', 123, false]; // 报错:长度超出限制
// t = [123, 'hello']; // 报错:位置类型不匹配
3.8 enum 枚举
枚举(enum)用于定义一组固定的常量集合,常用于状态、选项、标识等场景,默认从 0 开始自增。
typescript
运行
// 1. 默认枚举:值从 0 开始递增
enum Color {
Red, // 0
Blue, // 1
Black // 2
}
console.log(Color.Red); // 0
console.log(Color[0]); // Red
// 2. 自定义初始值,后续自动递增
enum Color2 {
Red = 6, // 6
Blue, // 7
Black // 8
}
// 3. 枚举实战:约束对象属性
let phone: { name: string; price: number; color: Color };
phone = { name: '华为', price: 6500, color: Color.Red };
// 枚举判断
if (phone.color === Color.Red) {
console.log('手机为红色');
}
四、自定义类型 type
使用 type 可以给复杂类型起别名,灵活组合字面量、枚举、对象等类型,实现高度自定义约束。
typescript
运行
// 1. 用字面量联合定义年级类型
type Grade = 1 | 2 | 3;
// 2. 枚举定义性别
enum Gender {
Male,
Female
}
// 3. 组合成学生自定义类型
type Student = {
name: string;
age: number;
gender: Gender;
grade: Grade;
};
// 使用自定义类型
let s1: Student;
s1 = { name: '张三', age: 18, gender: Gender.Male, grade: 1 };
五、抽象类
抽象类用 abstract 修饰,核心特性:
- 不能被实例化,只能被子类继承;
- 可以包含普通属性、普通方法、抽象方法(无具体实现);
- 子类继承后,必须实现父类的所有抽象方法。
typescript
运行
// 定义抽象类
abstract class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 抽象方法:只有声明,没有实现
abstract speak(): void;
// 普通方法
walk() {
console.log('正在行走');
}
}
// 子类继承抽象类(extends)
class Teacher extends Person {
constructor(name: string, age: number) {
super(name, age); // 调用父类构造器
}
// 必须实现抽象方法
speak() {
console.log(`我是老师:${this.name}`);
}
}
// const p = new Person('张三', 18); // 报错:抽象类无法实例化
const t = new Teacher('李老师', 40);
t.speak();
六、接口 Interface
接口(interface)是 TS 核心语法之一,主要用于约束对象结构、类的属性与方法。
6.1 基础用法:类实现接口
类通过 implements 关键字实现接口,必须补齐接口中所有属性和方法:
typescript
运行
// 定义接口
interface Person {
name: string;
age: number;
speak(): void;
}
// 类实现接口
class Teacher implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
speak() {
console.log(`我是${this.name}`);
}
}
6.2 接口特性:可重复声明并自动合并
同一个接口可以多次声明,TS 会自动将所有声明的属性、方法合并:
typescript
运行
interface PersonInter {
name: string;
age: number;
}
// 重复声明,自动合并
interface PersonInter {
speak(): void;
}
// 最终接口包含 name、age、speak
class Student implements PersonInter {
name: string;
age: number;
speak() {}
}
6.3 接口 vs 自定义类型 type
两者都可以定义对象类型,核心区别:
- 接口:支持重复声明合并、可以约束类结构(
implements),优先用于描述对象 / 类结构; - type:单纯的类型别名,不支持重复合并,支持联合类型、交叉类型,灵活度更高。
6.4 接口 vs 抽象类
表格
| 对比项 | 抽象类 | 接口 |
|---|---|---|
| 关键字 | extends 继承 |
implements 实现 |
| 方法 | 可包含普通方法 + 抽象方法 | 仅能声明抽象方法(无实现) |
| 构造器 | 可以拥有构造器 | 不允许拥有构造器 |
七、属性修饰符
TS 为类的属性提供了 4 种修饰符,控制属性的访问权限和特性:
表格
| 修饰符 | 作用 | 访问范围 |
|---|---|---|
readonly |
只读属性 | 仅可读,无法修改 |
public |
公开属性(默认) | 类内部、子类、实例都可访问修改 |
protected |
受保护属性 | 类内部、子类可访问,实例无法访问 |
private |
私有属性 | 仅当前类内部可访问 |
typescript
运行
class User {
public name: string;
private id: string;
protected age: number;
readonly sex: string = '男';
constructor(name: string, id: string, age: number) {
this.name = name;
this.id = id;
this.age = age;
}
}
const u = new User('张三', '001', 18);
console.log(u.name);
// console.log(u.id); // 报错:私有属性
// console.log(u.age); // 报错:受保护属性
// u.sex = '女'; // 报错:只读属性不可修改
八、泛型(TS 核心难点)
泛型用来解决类型不确定的问题:定义函数 / 类时,无法提前确定数据类型,使用泛型可以实现类型复用、类型约束,大幅提升代码通用性。
8.1 基础泛型函数
用 <T> 定义泛型占位符(T 是自定义名称,常用 T/K/V):
typescript
运行
// T 代表任意类型,入参和返回值类型保持一致
function test<T>(arg: T): T {
return arg;
}
test(10); // TS自动推断 T = number
test<string>('hi'); // 手动指定泛型类型
8.2 多泛型参数
支持同时定义多个泛型:
typescript
运行
function test<T, K>(a: T, b: K): K {
return b;
}
test<number, string>(10, 'hello');
8.3 类中的泛型
泛型同样可以作用于类,约束类的属性、方法类型:
typescript
运行
class MyClass<T> {
prop: T;
constructor(prop: T) {
this.prop = prop;
}
}
const c1 = new MyClass<number>(100);
8.4 泛型约束
通过 extends 限制泛型的范围,要求泛型必须满足指定结构:
typescript
运行
// 定义接口:必须包含 length 属性
interface Demo {
length: number;
}
// 约束 T 必须实现 Demo 接口(拥有 length)
function getLength<T extends Demo>(arg: T): number {
return arg.length;
}
getLength('123'); // 字符串有 length,合法
getLength({ length: 10 }); // 对象有 length,合法
// getLength(10); // 报错:number 没有 length 属性
九、总结
本文完整梳理了 TypeScript 从基础类型、语法到抽象类、接口、泛型的全套核心知识点,覆盖了日常业务开发 90% 以上的 TS 用法:
- 基础部分重点掌握类型声明、类型推断、八大内置类型,分清
any/unknown、object/ 元组 / 枚举的区别; - 进阶部分理解
type自定义类型、抽象类、接口的使用场景与差异; - 难点部分吃透泛型和属性修饰符,泛型是 TS 实现高阶复用的关键。
TypeScript 的学习离不开实战练习,掌握以上知识点后,可以结合 Vue、React 等前端框架进行项目实操,进一步巩固类型思维,彻底发挥 TS 的强类型优势。
更多推荐

所有评论(0)