TS安装
js
npm install -g typescript
pnpm add -g typescript
tsc --version // 验证
静态类型(Static Typing)
这是 TS 最核心的特性。在 JavaScript 中,变量类型是动态的(运行时确定),而 TS 在编译阶段就会检查类型,提前发现错误。
ts
// TS中声明变量时指定类型
let username: string = "张三"; // 只能赋值字符串
let age: number = 25; // 只能赋值数字
// 如果赋值类型错误,编译阶段就会报错(无需运行代码)
// age = "25"; // ❌ 错误:不能将类型"string"分配给类型"number"
类型注解(Type Annotation)
这是 TS 中最基础的语法,显式地为变量、函数参数、函数返回值指定类型,是实现静态类型检查的基础,你可以把它理解为 "给代码贴类型标签"。
ts
// 变量类型注解
let count: number = 10; // 注解count为数字类型
let isActive: boolean = true; // 注解为布尔类型
// 函数参数 + 返回值注解
function add(a: number, b: number): number {
return a + b;
}
// 函数返回值为对象的注解(结合对象类型)
function getUser(): { id: number; name: string } {
return { id: 1, name: "张三" };
}
注意:类型注解是 "手动指定",和 "类型推断"(TS 自动推导)是互补的,注解可以覆盖推断,也能在推断不明确时明确类型。
接口(Interface)
用来定义对象的形状(属性和方法),是 TS 中最常用的类型约束方式,支持扩展和可选属性。
-
可选属性、只读属性
-
函数类型接口
-
接口继承
ts
// 1. 定义对象接口(描述用户对象的结构) - 可选属性 + 只读属性
interface User {
readonly id: number; // 只读属性,初始化后不可修改
name: string;
age?: number; // 可选属性(可传可不传)
}
// 使用接口约束变量类型
const user: User = {
id: 1,
name: "李四"
// age可选,这里可以不写
};
// user.id = 2; // ❌ 错误:只读属性不能修改
// 2. 函数类型接口(约束函数的参数和返回值)
interface Calculate {
(a: number, b: number): number;
}
const add: Calculate = (x, y) => x + y; // 符合接口约束
const sub: Calculate = (x, y) => x - y;
// 3. 接口继承(复用已有接口)
interface AdminUser extends User {
role: string; // 新增管理员专属属性
}
const admin: AdminUser = { id: 2, name: "管理员", role: "super" };
我们这里定义了一个 User 接口,它有三个属性:id 数字类型、name 字符串类型、age 数字类型,后面有个问号表示可选属性,可以不提供。
接着我们创建了一个 user 对象,它的类型是 User 。如果我们尝试给 user 添加一个接口中没有定义的属性,如 address,TS就会报错。
类(Class)
TS 增强了 ES6 的 Class,添加了访问修饰符、抽象类、接口实现等面向对象特性,让类的设计更严谨。
ts
// 1. 访问修饰符(public/protected/private)
class Person {
public name: string; // 公有的(默认),任意地方可访问
protected age: number; // 受保护的,仅本类和子类可访问
private id: number; // 私有的,仅本类可访问
// constructor 是构造函数,在创建对象时调用
constructor(name: string, age: number, id: number) {
this.name = name;
this.age = age;
this.id = id;
}
// getInfo 是一个方法,返回字符串类型
public getInfo(): string {
return `${this.name} - ${this.age}`;
}
}
const person = new Person("王五", 30, 1001);
console.log(person.name); // ✅ 可访问
// console.log(person.age); // ❌ 错误:protected仅类内部/子类访问
// console.log(person.id); // ❌ 错误:private仅类内部访问
// 2. 子类继承
class Student extends Person {
constructor(name: string, age: number, id: number) {
super(name, age, id); // 调用父类构造函数
}
showAge() {
console.log(this.age); // ✅ 子类可访问protected属性
}
}
// 3. 抽象类(abstract):不能实例化,只能被继承,用于定义规范
abstract class Shape {
abstract getArea(): number; // 抽象方法,子类必须实现
}
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
getArea(): number { // 必须实现抽象方法
return Math.PI * this.radius **2;
}
}
// 4. 类实现接口(implements)
interface Printable {
print(): void;
}
class Document implements Printable {
print(): void { // 必须实现接口的print方法
console.log("打印文档");
}
}
装饰器(Decorator)
装饰器是 TS 的实验性特性(需手动开启配置),本质是一个函数,用于扩展类、方法、属性、参数的行为,是 AOP(面向切面编程)的实现方式,常见于框架(如 Angular、NestJS)。 基础用法(需配置 tsconfig.json:"experimentalDecorators": true):
ts
// 1. 类装饰器:修饰整个类
function LogClass(target: any) {
console.log("类被装饰了:", target);
// 可以扩展类的属性/方法
target.prototype.version = "1.0";
}
@LogClass // 应用类装饰器
class Product {
name: string;
constructor(name: string) {
this.name = name;
}
}
const product = new Product("手机");
console.log((product as any).version); // 输出1.0
// 2. 方法装饰器:修饰类的方法
function LogMethod(
target: any,
methodName: string,
descriptor: PropertyDescriptor
) {
// 保存原方法
const originalMethod = descriptor.value;
// 重写方法(添加日志逻辑)
descriptor.value = function (...args: any[]) {
console.log(`调用方法${methodName},参数:`, args);
return originalMethod.apply(this, args);
};
}
class Calculator {
@LogMethod // 应用方法装饰器
add(a: number, b: number) {
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2); // 输出:调用方法add,参数:[1,2],返回3
泛型(Generics)
解决 "类型复用" 问题,让函数 / 类 / 接口支持多种类型,同时保留类型检查(创建可重用的组件,然后这些组件可以处理多种数据类型)。核心是 "类型参数化"。
ts
// 1. 泛型函数:支持任意类型的数组,返回第一个元素
function getFirst<T>(arr: T[]): T {
return arr[0];
}
// 使用时自动推导类型
const str = getFirst(["a", "b"]); // str类型为string
const num = getFirst([1, 2]); // num类型为number
// 2. 泛型类
class Box<T> {
private content: T;
constructor(content: T) {
this.content = content;
}
getContent(): T {
return this.content;
}
}
// 实例化时指定类型
const stringBox = new Box<string>("hello");
console.log(stringBox.getContent()); // 类型为string
const numberBox = new Box<number>(123);
console.log(numberBox.getContent()); // 类型为number
// 3. 泛型接口
interface Pair<K, V> {
key: K;
value: V;
}
const pair: Pair<string, number> = { key: "age", value: 25 };
类型推断与类型断言
类型推断:TS 会自动推导变量类型(无需手动指定),简化代码。
ts
let msg = "hello"; // TS自动推断msg为string类型
类型断言:告诉 TS "我比你更清楚这个值的类型",强制指定类型(仅编译阶段有效)。
ts
const input = document.getElementById("input") as HTMLInputElement;
// 断言input是输入框元素,可直接使用value属性
console.log(input.value);
枚举
定义一组命名的常量,让代码更易读(比如状态码、选项等)。
ts
// 定义枚举
enum Status {
Success = 200,
Error = 500,
NotFound = 404
}
// 使用枚举
console.log(Status.Success); // 输出200