T TypeScript是什么?

TypeScript 是 JavaScript 的一个超集(加强版),由微软开发。它最大的特点是添加了类型系统,让代码更健壮、更易维护。

JavaScript vs TypeScript

JavaScript: let name = “张三”; // 可以随时改变为数字或其他类型

TypeScript: let name: string = “张三”; // 明确指定为字符串类型

为什么使用TypeScript?
  • 更早发现代码错误(编译时报错)
  • 代码提示更智能
  • 重构大型项目更安全
  • 更容易理解代码结构

B 基础类型

TypeScript 提供了多种基础类型,帮助定义变量的数据类型:

// 字符串类型
let name: string = “李四”;

// 数字类型(整数、小数都算)
let age: number = 25;

// 布尔类型(true/false)
let isStudent: boolean = true;

// 数组类型(两种写法)
let hobbies: string[] = [“阅读”, “旅行”];
let scores: Array<number> = [90, 85, 95];

// 元组:固定长度和类型的数组
let person: [string, number] = [“王五”, 30];

// 枚举:一组有名字的常量
enum Direction { Up, Down, Left, Right }
let move: Direction = Direction.Up;

// Any:任意类型(尽量少用)
let something: any = “可以是任何值”;
something = 10; // 不会报错

// Void:没有返回值(常用于函数)
function sayHello(): void {
  console.log(“Hello!”);
}
类型推断: TypeScript 能自动推断类型,不一定要显式声明:

let username = "小明"; // TypeScript自动知道是string类型

V 变量声明

TypeScript 使用 letconst 声明变量:

// let: 声明后可以重新赋值
let count: number = 10;
count = 20; // 正确

// const: 声明后不能重新赋值(常量)
const PI: number = 3.14;
// PI = 3.14159; // 错误!常量不能重新赋值
最佳实践:
  • 优先使用 const,除非需要重新赋值
  • 变量名要有意义,使用驼峰命名法(如:userName)
  • 避免使用 var(旧方式,作用域规则不同)

F 函数

TypeScript 增强了函数功能,可以指定参数类型和返回值类型:

// 基本函数:指定参数和返回类型
function add(x: number, y: number): number {
  return x + y;
}

// 可选参数:参数名后加问号?
function greet(name: string, age?: number): string {
  if (age) {
    return `你好,${name},你${age}岁了!`;
  } else {
    return `你好,${name}!`;
  }
}

// 默认参数值
function createUser(name: string, role: string = “user”): void {
  console.log(`创建用户:${name},角色:${role}`);
}

// 剩余参数(收集多个参数到数组)
function sum(…numbers: number[]): number {
  return numbers.reduce((a, b) => a + b, 0);
}
箭头函数: 简洁的函数写法
const multiply = (a: number, b: number): number => a * b;

I 接口(Interface)

接口用于定义对象的结构:

// 定义一个用户接口
interface User {
  name: string;
  age: number;
  email?: string; // 可选属性
  readonly id: number; // 只读属性
}

// 使用接口
const user1: User = {
  name: “张三”,
  age: 28,
  id: 1001
};

// user1.id = 1002; // 错误!id是只读的
接口的作用:
  • 定义对象应该有哪些属性
  • 定义函数的参数结构
  • 作为类的规范

C 类(Class)

TypeScript 增强了 JavaScript 的类,增加了访问修饰符等特性:

class Animal {
  // 属性(默认是public)
  name: string;
  // 私有属性(只能在类内部访问)
  private age: number;

  // 构造函数
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  // 方法
  speak(): void {
    console.log(`${this.name}叫了一声`);
  }

  // 获取私有属性
  getAge(): number {
    return this.age;
  }
}

// 继承
class Dog extends Animal {
  breed: string;

  constructor(name: string, age: number, breed: string) {
    super(name, age); // 调用父类构造函数
    this.breed = breed;
  }

  // 重写方法
  speak(): void {
    console.log(`${this.name}汪汪叫!`);
  }
}

const myDog = new Dog(“旺财”, 3, “金毛”);
myDog.speak(); // 输出:旺财汪汪叫!

G 泛型(Generics)

泛型让组件可以支持多种类型,提高代码复用性:

// 简单泛型函数
function identity<T>(arg: T): T {
  return arg;
}

// 使用:
let output1 = identity<string>(“hello”); // T是string
let output2 = identity(42); // 自动推断T是number

// 泛型接口
interface Box<T> {
  content: T;
}

let box: Box<string> = { content: “礼物” };

// 泛型类
class Container<T> {
  value: T;

  constructor(value: T) {
    this.value = value;
  }

  getValue(): T {
    return this.value;
  }
}

const numContainer = new Container<number>(100);
const strContainer = new Container(“文本”); // 自动推断
泛型应用场景:
  • 创建可复用的组件
  • 处理数组、集合等数据结构
  • API返回值的类型定义

A 高级类型

TypeScript 提供了一些高级类型工具:

// 联合类型:允许一个变量是多种类型之一
let id: string | number;
id = “ABC123”; // OK
id = 1001; // OK
// id = true; // 错误

// 类型别名:为类型创建新名字
type UserID = string | number;
const userId: UserID = “U1001”;

// 类型断言:告诉编译器”我知道这个值的类型”
let someValue: any = “这是一个字符串”;
let strLength: number = (someValue as string).length;

// 另一种写法(效果相同)
let strLength2: number = (<string>someValue).length;

M 模块系统

TypeScript 支持模块化开发:

// math.ts 文件
export function add(a: number, b: number): number {
  return a + b;
}

export const PI = 3.14;

// 默认导出(一个模块只有一个)
export default class Calculator {
  // …
}

// app.ts 文件
// 导入单个
import { add, PI } from “./math”;
// 导入默认导出
import Calculator from “./math”;
// 全部导入
import * as math from “./math”;
模块化开发的好处:
  • 代码组织更清晰
  • 避免命名冲突
  • 提高代码复用性
  • 便于团队协作