TypeScript 快速上手指南

1. 环境搭建

1.1 安装配置

# 安装 TypeScript
npm install -g typescript

# 初始化 TypeScript 配置
tsc --init

1.2 基础配置文件

{
  "compilerOptions": {
    "target": "es5",                    // 编译目标版本
    "module": "commonjs",               // 模块系统
    "sourceMap": true,                  // 生成源码映射
    "typeRoots": [                      // 类型定义文件路径
      "./typings",
      "./node_modules/@types"
    ]
  }
}

2. 基础语法入门

2.1 类型声明

// 基本类型
let isDone: boolean = false;
let count: number = 10;
let name: string = "TypeScript";
let list: number[] = [1, 2, 3];        // 数组
let tuple: [string, number] = ["hello", 10]; // 元组

// 特殊类型
let notSure: any = 4;                  // 任意类型
let u: undefined = undefined;          
let n: null = null;
let v: void = undefined;               // 空值
let nv: never = (() => { throw new Error(); })(); // 永不返回

// 对象类型
interface Person {
  name: string;
  age?: number;                        // 可选属性
  readonly id: number;                 // 只读属性
}

// 联合类型和类型别名
type StringOrNumber = string | number;
let value: StringOrNumber = "hello";
value = 42;                           // 合法

// 字面量类型
type Direction = "North" | "South" | "East" | "West";
let dir: Direction = "North";         // 只能是这四个值之一

2.2 函数类型

// 函数声明
function add(x: number, y: number): number {
  return x + y;
}

// 函数类型接口
interface MathFunc {
  (x: number, y: number): number;
}
let multiply: MathFunc = (x, y) => x * y;

// 可选参数和默认参数
function buildName(firstName: string, lastName?: string): string;
function buildName(firstName: string, lastName = "Smith"): string {
  return `${firstName} ${lastName}`;
}

// 函数重载
function padding(all: number);
function padding(topBottom: number, leftRight: number);
function padding(top: number, right: number, bottom: number, left: number);
function padding(a: number, b?: number, c?: number, d?: number) {
  // 实现代码
}

2.3 类型断言和类型守卫

// 类型断言
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length; // 另一种语法

// 类型守卫
function isString(value: any): value is string {
  return typeof value === "string";
}

function processValue(value: string | number) {
  if (isString(value)) {
    // 这里 TypeScript 知道 value 是 string 类型
    console.log(value.toUpperCase());
  } else {
    // 这里 TypeScript 知道 value 是 number 类型
    console.log(value.toFixed(2));
  }
}

2.4 模块使用

// 导入模块
import * as path from 'path';           // 整体导入
import { parse } from 'path';           // 按需导入
import myModule = require('./mymodule'); // CommonJS 导入

// 导出模块
export interface User {
  name: string;
  age: number;
}

2.5 泛型使用

// 泛型类
class Repository<T> {
  constructor(private data: T[]) {}
  get(id: number): T { ... }
}

// 泛型函数
function transform<T>(items: any[], mapper: (item: any) => T): T[] {
  return items.map(mapper);
}

3. 工程实践

3.1 与 JavaScript 互操作

类型声明文件(.d.ts)
// 为已有的 JS 库添加类型声明
declare module 'crypto-js' {
  export function SHA256(message: string): string;
}
安装第三方库类型定义
# 安装依赖库
npm install jquery --save

# 安装类型定义
npm install @types/jquery --save-dev

3.2 开发调试

VS Code 调试配置
{
  "compilerOptions": {
    "sourceMap": true,
    "outDir": "./dist"
  }
}
常用编译命令
命令说明
tsc --watch监听文件变化并实时编译
tsc --project tsconfig.json使用指定配置编译

3.3 最佳实践

  • 使用 strict 模式确保类型安全
  • 优先使用接口(Interface)定义类型
  • 合理使用类型推导,避免过度类型标注
  • 保持良好的代码组织,遵循模块化原则

4. 常见问题解决

类型定义相关

  • 检查 typeRoots 路径配置
  • 确认是否安装了对应的 @types
  • 检查 tsconfig.json 中的 noImplicitAny 设置

编译相关

  • 确保 tsconfig.json 配置正确
  • 使用 --watch 模式实时发现问题
  • 查看生成的 sourceMap 定位问题

5. 高级使用技巧

5.1 条件类型

// 条件类型基础
type TypeName<T> = T extends string
  ? "string"
  : T extends number
  ? "number"
  : T extends boolean
  ? "boolean"
  : "object";

// 分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
type StrArrOrNumArr = ToArray<string | number>; // string[] | number[]

// infer 关键字使用
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
type func = () => number;
type funcReturnType = ReturnType<func>; // number

5.2 映射类型

// 只读映射
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

// 可选映射
type Partial<T> = {
  [P in keyof T]?: T[P];
};

// 记录映射
type Record<K extends keyof any, T> = {
  [P in K]: T;
};

// 实际应用
interface Todo {
  title: string;
  description: string;
}

type ReadonlyTodo = Readonly<Todo>;
type PartialTodo = Partial<Todo>;
type TodoRecord = Record<'home' | 'work', Todo>;

5.3 装饰器使用

// 类装饰器
function classDecorator<T extends { new (...args: any[]): {} }>(constructor: T) {
  return class extends constructor {
    newProperty = "new property";
    hello = "override";
  };
}

// 方法装饰器
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  let originalMethod = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log(`Calling ${propertyKey} with`, args);
    return originalMethod.apply(this, args);
  };
  return descriptor;
}

@classDecorator
class Example {
  @log
  method(arg: string) {
    return `Method called with ${arg}`;
  }
}

5.4 高级类型工具

// 联合转交叉
type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 提取属性类型
type PropType<T, Path extends string> = 
  Path extends keyof T 
    ? T[Path] 
    : Path extends `${infer K}.${infer R}`
      ? K extends keyof T
        ? PropType<T[K], R>
        : never
      : never;

// 字符串模板类型
type EventName<T extends string> = `${T}Changed`;
type UserEvents = EventName<'name' | 'age'>; // 'nameChanged' | 'ageChanged'

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值