Skip to content

TypeScript基础2024:Vue.js开发者掌握类型安全编程完整指南

📊 SEO元描述:2024年最新TypeScript基础教程,详解类型系统、接口、泛型、装饰器。专为Vue.js开发者设计,包含完整类型安全编程方案。

核心关键词:TypeScript基础2024、Vue TypeScript、类型安全编程、TypeScript接口、TypeScript泛型

长尾关键词:TypeScript基础怎么学、Vue TypeScript最佳实践、TypeScript类型系统详解、TypeScript泛型如何使用、前端类型安全编程


📚 TypeScript基础学习目标与核心收获

通过本节TypeScript基础深度教程,你将系统性掌握:

  • TypeScript核心概念:深入理解类型系统、编译原理和开发环境配置
  • 基础类型系统:掌握原始类型、对象类型、数组类型和函数类型
  • 高级类型特性:学会使用接口、泛型、联合类型和交叉类型
  • 面向对象编程:掌握类、继承、抽象类和访问修饰符
  • 模块系统应用:学会模块导入导出和命名空间管理
  • 实用工具类型:掌握内置工具类型和自定义类型工具

🎯 适合人群

  • JavaScript开发者希望学习类型安全编程
  • Vue.js开发者需要在项目中引入TypeScript
  • 前端工程师追求更高的代码质量和开发效率
  • 团队技术负责人需要制定TypeScript技术规范

🌟 为什么选择TypeScript?如何理解类型系统?

为什么选择TypeScript?这是现代前端开发的重要决策。TypeScript通过静态类型检查,能够在编译时发现错误、提供更好的IDE支持、增强代码可维护性,特别是在大型项目中。TypeScript是现代Vue.js开发的重要技术选择。

TypeScript的核心价值

  • 🎯 类型安全:编译时错误检查,减少运行时错误
  • 🔧 开发体验:更好的IDE支持,智能提示和重构
  • 💡 代码质量:强制类型约束,提升代码可读性和维护性
  • 📚 团队协作:类型定义作为文档,降低沟通成本
  • 🚀 重构支持:安全的大规模代码重构能力

💡 学习建议:TypeScript是JavaScript的超集,渐进式学习,从基础类型开始,逐步掌握高级特性

TypeScript环境配置与基础语法

TypeScript需要编译环境和类型定义支持:

typescript
// 基础类型演示
// types/basic.ts - TypeScript基础类型示例

// 1. 原始类型
let isDone: boolean = false
let count: number = 42
let name: string = "Vue Developer"
let nothing: null = null
let notDefined: undefined = undefined

// 2. 数组类型
let numbers: number[] = [1, 2, 3, 4, 5]
let strings: Array<string> = ["vue", "react", "angular"]
let mixed: (string | number)[] = ["vue", 3, "typescript"]

// 3. 元组类型
let tuple: [string, number] = ["vue", 3]
let namedTuple: [name: string, version: number] = ["Vue.js", 3]

// 4. 枚举类型
enum Color {
  Red = "red",
  Green = "green",
  Blue = "blue"
}

enum Status {
  Pending = 0,
  Success = 1,
  Error = 2
}

let currentColor: Color = Color.Red
let requestStatus: Status = Status.Pending

// 5. Any类型(谨慎使用)
let dynamic: any = 42
dynamic = "now it's a string"
dynamic = false

// 6. Unknown类型(更安全的any)
let userInput: unknown = getUserInput()
if (typeof userInput === "string") {
  console.log(userInput.toUpperCase()) // 类型守卫后安全使用
}

// 7. Void类型
function logMessage(message: string): void {
  console.log(message)
}

// 8. Never类型
function throwError(message: string): never {
  throw new Error(message)
}

function infiniteLoop(): never {
  while (true) {
    // 无限循环
  }
}

// 9. 对象类型
let user: {
  id: number
  name: string
  email?: string // 可选属性
  readonly createdAt: Date // 只读属性
} = {
  id: 1,
  name: "John Doe",
  createdAt: new Date()
}

// 10. 函数类型
let add: (a: number, b: number) => number = (a, b) => a + b

// 函数重载
function process(value: string): string
function process(value: number): number
function process(value: string | number): string | number {
  if (typeof value === "string") {
    return value.toUpperCase()
  }
  return value * 2
}

// 工具函数示例
function getUserInput(): unknown {
  return Math.random() > 0.5 ? "hello" : 42
}

// 类型断言
let someValue: unknown = "this is a string"
let strLength: number = (someValue as string).length
// 或者使用尖括号语法(在JSX中不推荐)
let strLength2: number = (<string>someValue).length

// 字面量类型
let direction: "up" | "down" | "left" | "right" = "up"
let httpMethod: "GET" | "POST" | "PUT" | "DELETE" = "GET"

// 类型别名
type Point = {
  x: number
  y: number
}

type EventHandler = (event: Event) => void

let point: Point = { x: 10, y: 20 }
let clickHandler: EventHandler = (event) => {
  console.log("Clicked at", event.target)
}

export {
  Color,
  Status,
  Point,
  EventHandler,
  add,
  process,
  logMessage
}
typescript
// interfaces/user.ts - 接口定义示例

// 基础接口
interface User {
  id: number
  name: string
  email: string
  avatar?: string // 可选属性
  readonly createdAt: Date // 只读属性
}

// 接口继承
interface AdminUser extends User {
  permissions: string[]
  lastLogin: Date
}

interface SuperAdmin extends AdminUser {
  canDeleteUsers: boolean
  systemAccess: boolean
}

// 函数接口
interface SearchFunction {
  (source: string, subString: string): boolean
}

interface EventListener {
  (event: Event): void
}

// 可索引接口
interface StringArray {
  [index: number]: string
}

interface StringDictionary {
  [key: string]: string
}

// 混合类型接口
interface Counter {
  (start: number): string
  interval: number
  reset(): void
}

// 接口合并(声明合并)
interface Window {
  customProperty: string
}

interface Window {
  anotherProperty: number
}

// 现在Window接口包含两个属性

// 泛型接口
interface GenericIdentityFn<T> {
  (arg: T): T
}

interface Repository<T> {
  findById(id: number): T | null
  save(entity: T): T
  delete(id: number): boolean
  findAll(): T[]
}

// 条件类型接口
interface ApiResponse<T> {
  data: T
  success: boolean
  message: string
  timestamp: Date
}

// 实际使用示例
const user: User = {
  id: 1,
  name: "John Doe",
  email: "john@example.com",
  createdAt: new Date()
}

const admin: AdminUser = {
  ...user,
  permissions: ["read", "write", "delete"],
  lastLogin: new Date()
}

const searchFn: SearchFunction = (source, subString) => {
  return source.indexOf(subString) > -1
}

const stringArray: StringArray = ["Hello", "World"]
const stringDict: StringDictionary = {
  name: "Vue.js",
  type: "Framework"
}

// 泛型接口使用
const userRepository: Repository<User> = {
  findById: (id) => user,
  save: (entity) => entity,
  delete: (id) => true,
  findAll: () => [user]
}

const apiResponse: ApiResponse<User[]> = {
  data: [user],
  success: true,
  message: "Users fetched successfully",
  timestamp: new Date()
}

export {
  User,
  AdminUser,
  SuperAdmin,
  SearchFunction,
  EventListener,
  Repository,
  ApiResponse,
  userRepository,
  apiResponse
}
typescript
// generics/advanced.ts - 泛型高级应用

// 基础泛型函数
function identity<T>(arg: T): T {
  return arg
}

// 泛型约束
interface Lengthwise {
  length: number
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length) // 现在我们知道它有length属性
  return arg
}

// 使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key]
}

// 泛型类
class GenericNumber<T> {
  zeroValue: T
  add: (x: T, y: T) => T

  constructor(zeroValue: T, addFn: (x: T, y: T) => T) {
    this.zeroValue = zeroValue
    this.add = addFn
  }
}

// 泛型约束使用类型参数
function create<T extends object>(c: new() => T): T {
  return new c()
}

// 条件类型
type NonNullable<T> = T extends null | undefined ? never : T

type FunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? K : never
}[keyof T]

type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>

// 映射类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P]
}

type Partial<T> = {
  [P in keyof T]?: T[P]
}

type Required<T> = {
  [P in keyof T]-?: T[P]
}

// 实用工具类型示例
interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: Date
}

// Pick - 选择特定属性
type TodoPreview = Pick<Todo, "title" | "completed">

// Omit - 排除特定属性
type TodoInfo = Omit<Todo, "completed" | "createdAt">

// Record - 构造记录类型
type PageInfo = Record<"home" | "about" | "contact", { title: string; url: string }>

// 高级泛型示例
class DataService<T> {
  private items: T[] = []

  add(item: T): void {
    this.items.push(item)
  }

  get(index: number): T | undefined {
    return this.items[index]
  }

  getAll(): T[] {
    return [...this.items]
  }

  filter<K extends keyof T>(key: K, value: T[K]): T[] {
    return this.items.filter(item => item[key] === value)
  }

  map<U>(fn: (item: T) => U): U[] {
    return this.items.map(fn)
  }
}

// 使用示例
const numberService = new DataService<number>()
numberService.add(1)
numberService.add(2)

const userService = new DataService<User>()
userService.add({
  id: 1,
  name: "John",
  email: "john@example.com",
  createdAt: new Date()
})

// 函数重载与泛型结合
function combine<T>(a: T[], b: T[]): T[]
function combine<T>(a: T, b: T): T
function combine<T>(a: T | T[], b: T | T[]): T | T[] {
  if (Array.isArray(a) && Array.isArray(b)) {
    return [...a, ...b]
  }
  return b // 简化实现
}

// 条件类型的实际应用
type ApiResult<T> = T extends string 
  ? { message: T } 
  : T extends number 
  ? { code: T } 
  : { data: T }

// 递归类型
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]
}

export {
  identity,
  loggingIdentity,
  getProperty,
  GenericNumber,
  DataService,
  combine,
  Todo,
  TodoPreview,
  TodoInfo,
  PageInfo,
  ApiResult,
  DeepReadonly
}

TypeScript基础语法核心特性

  • 静态类型:编译时类型检查,提前发现错误
  • 类型推断:智能类型推断,减少显式类型声明
  • 接口定义:结构化类型定义,增强代码可读性
  • 泛型支持:类型参数化,提高代码复用性

面向对象编程特性

TypeScript如何支持面向对象编程?有哪些高级特性?

TypeScript面向对象编程提供了完整的类、继承、抽象类等特性:

typescript
// classes/oop.ts - 面向对象编程示例

// 基础类定义
class Animal {
  // 属性声明
  protected name: string
  private age: number
  public species: string

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

  // 方法定义
  public makeSound(): void {
    console.log(`${this.name} makes a sound`)
  }

  // Getter和Setter
  get animalAge(): number {
    return this.age
  }

  set animalAge(age: number) {
    if (age > 0) {
      this.age = age
    }
  }

  // 静态方法
  static createAnimal(name: string, species: string): Animal {
    return new Animal(name, 1, species)
  }
}

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

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

  // 方法重写
  public makeSound(): void {
    console.log(`${this.name} barks: Woof! Woof!`)
  }

  // 新方法
  public fetch(): void {
    console.log(`${this.name} fetches the ball`)
  }

  // 访问受保护的属性
  public introduce(): void {
    console.log(`Hi, I'm ${this.name}, a ${this.breed}`)
  }
}

// 抽象类
abstract class Shape {
  protected color: string

  constructor(color: string) {
    this.color = color
  }

  // 抽象方法
  abstract calculateArea(): number
  abstract draw(): void

  // 具体方法
  public getColor(): string {
    return this.color
  }
}

// 实现抽象类
class Circle extends Shape {
  private radius: number

  constructor(color: string, radius: number) {
    super(color)
    this.radius = radius
  }

  calculateArea(): number {
    return Math.PI * this.radius * this.radius
  }

  draw(): void {
    console.log(`Drawing a ${this.color} circle with radius ${this.radius}`)
  }
}

class Rectangle extends Shape {
  private width: number
  private height: number

  constructor(color: string, width: number, height: number) {
    super(color)
    this.width = width
    this.height = height
  }

  calculateArea(): number {
    return this.width * this.height
  }

  draw(): void {
    console.log(`Drawing a ${this.color} rectangle ${this.width}x${this.height}`)
  }
}

// 接口实现
interface Flyable {
  fly(): void
  altitude: number
}

interface Swimmable {
  swim(): void
  depth: number
}

// 多接口实现
class Duck extends Animal implements Flyable, Swimmable {
  altitude: number = 0
  depth: number = 0

  constructor(name: string, age: number) {
    super(name, age, "Bird")
  }

  fly(): void {
    this.altitude = 100
    console.log(`${this.name} is flying at ${this.altitude} meters`)
  }

  swim(): void {
    this.depth = 2
    console.log(`${this.name} is swimming at ${this.depth} meters deep`)
  }

  makeSound(): void {
    console.log(`${this.name} quacks: Quack! Quack!`)
  }
}

// 泛型类
class Container<T> {
  private items: T[] = []

  add(item: T): void {
    this.items.push(item)
  }

  get(index: number): T | undefined {
    return this.items[index]
  }

  getAll(): T[] {
    return [...this.items]
  }

  size(): number {
    return this.items.length
  }

  clear(): void {
    this.items = []
  }
}

// 装饰器(实验性功能)
function sealed(constructor: Function) {
  Object.seal(constructor)
  Object.seal(constructor.prototype)
}

function enumerable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.enumerable = value
  }
}

@sealed
class SealedClass {
  @enumerable(false)
  public method() {
    console.log("This method is not enumerable")
  }
}

// 使用示例
const dog = new Dog("Buddy", 3, "Golden Retriever")
dog.makeSound() // Buddy barks: Woof! Woof!
dog.fetch() // Buddy fetches the ball
dog.introduce() // Hi, I'm Buddy, a Golden Retriever

const circle = new Circle("red", 5)
console.log(`Circle area: ${circle.calculateArea()}`) // Circle area: 78.54

const duck = new Duck("Donald", 2)
duck.fly() // Donald is flying at 100 meters
duck.swim() // Donald is swimming at 2 meters deep
duck.makeSound() // Donald quacks: Quack! Quack!

const stringContainer = new Container<string>()
stringContainer.add("Hello")
stringContainer.add("World")
console.log(stringContainer.getAll()) // ["Hello", "World"]

export {
  Animal,
  Dog,
  Shape,
  Circle,
  Rectangle,
  Duck,
  Container,
  Flyable,
  Swimmable
}

面向对象编程核心特性

  • 🎯 封装:访问修饰符控制属性和方法的可见性
  • 🎯 继承:extends关键字实现类的继承
  • 🎯 多态:方法重写和接口实现
  • 🎯 抽象:抽象类和接口定义契约

💼 OOP提示:合理使用访问修饰符,优先使用组合而非继承,接口定义清晰的契约


🔧 模块系统与命名空间

TypeScript模块系统

TypeScript支持ES6模块和CommonJS模块系统:

typescript
// modules/math.ts - 数学工具模块
export const PI = 3.14159

export function add(a: number, b: number): number {
  return a + b
}

export function multiply(a: number, b: number): number {
  return a * b
}

export class Calculator {
  private history: string[] = []

  add(a: number, b: number): number {
    const result = a + b
    this.history.push(`${a} + ${b} = ${result}`)
    return result
  }

  subtract(a: number, b: number): number {
    const result = a - b
    this.history.push(`${a} - ${b} = ${result}`)
    return result
  }

  getHistory(): string[] {
    return [...this.history]
  }

  clearHistory(): void {
    this.history = []
  }
}

// 默认导出
export default class MathUtils {
  static factorial(n: number): number {
    if (n <= 1) return 1
    return n * MathUtils.factorial(n - 1)
  }

  static fibonacci(n: number): number {
    if (n <= 1) return n
    return MathUtils.fibonacci(n - 1) + MathUtils.fibonacci(n - 2)
  }

  static isPrime(n: number): boolean {
    if (n <= 1) return false
    if (n <= 3) return true
    if (n % 2 === 0 || n % 3 === 0) return false

    for (let i = 5; i * i <= n; i += 6) {
      if (n % i === 0 || n % (i + 2) === 0) return false
    }
    return true
  }
}

// 重新导出
export { default as MathUtilities } from './advanced-math'
typescript
// modules/user-service.ts - 用户服务模块
import { ApiResponse } from '../interfaces/user'

// 类型定义
export interface CreateUserRequest {
  name: string
  email: string
  password: string
}

export interface UpdateUserRequest {
  name?: string
  email?: string
}

export interface UserFilter {
  name?: string
  email?: string
  createdAfter?: Date
  createdBefore?: Date
}

// 服务类
export class UserService {
  private baseUrl: string

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
  }

  async createUser(userData: CreateUserRequest): Promise<ApiResponse<User>> {
    try {
      const response = await fetch(`${this.baseUrl}/users`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      throw new Error(`Failed to create user: ${error.message}`)
    }
  }

  async getUserById(id: number): Promise<ApiResponse<User>> {
    try {
      const response = await fetch(`${this.baseUrl}/users/${id}`)

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      throw new Error(`Failed to fetch user: ${error.message}`)
    }
  }

  async updateUser(id: number, userData: UpdateUserRequest): Promise<ApiResponse<User>> {
    try {
      const response = await fetch(`${this.baseUrl}/users/${id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      throw new Error(`Failed to update user: ${error.message}`)
    }
  }

  async deleteUser(id: number): Promise<ApiResponse<boolean>> {
    try {
      const response = await fetch(`${this.baseUrl}/users/${id}`, {
        method: 'DELETE'
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      throw new Error(`Failed to delete user: ${error.message}`)
    }
  }

  async getUsers(filter?: UserFilter): Promise<ApiResponse<User[]>> {
    try {
      const params = new URLSearchParams()

      if (filter) {
        Object.entries(filter).forEach(([key, value]) => {
          if (value !== undefined) {
            params.append(key, value.toString())
          }
        })
      }

      const url = `${this.baseUrl}/users${params.toString() ? '?' + params.toString() : ''}`
      const response = await fetch(url)

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      throw new Error(`Failed to fetch users: ${error.message}`)
    }
  }
}

// 工厂函数
export function createUserService(baseUrl: string): UserService {
  return new UserService(baseUrl)
}

// 单例模式
let userServiceInstance: UserService | null = null

export function getUserService(baseUrl?: string): UserService {
  if (!userServiceInstance) {
    if (!baseUrl) {
      throw new Error('Base URL is required for first initialization')
    }
    userServiceInstance = new UserService(baseUrl)
  }
  return userServiceInstance
}

命名空间应用

typescript
// namespaces/validation.ts - 验证命名空间
export namespace Validation {
  export interface Validator {
    isValid(value: any): boolean
    errorMessage: string
  }

  export class EmailValidator implements Validator {
    errorMessage = "Invalid email format"

    isValid(value: string): boolean {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
      return emailRegex.test(value)
    }
  }

  export class PasswordValidator implements Validator {
    errorMessage = "Password must be at least 8 characters with uppercase, lowercase, and number"

    isValid(value: string): boolean {
      const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/
      return passwordRegex.test(value)
    }
  }

  export class RequiredValidator implements Validator {
    errorMessage = "This field is required"

    isValid(value: any): boolean {
      return value !== null && value !== undefined && value !== ""
    }
  }

  export class LengthValidator implements Validator {
    errorMessage: string

    constructor(private minLength: number, private maxLength: number) {
      this.errorMessage = `Length must be between ${minLength} and ${maxLength} characters`
    }

    isValid(value: string): boolean {
      return value.length >= this.minLength && value.length <= this.maxLength
    }
  }

  export class ValidationResult {
    constructor(
      public isValid: boolean,
      public errors: string[] = []
    ) {}
  }

  export class FormValidator {
    private validators: Map<string, Validator[]> = new Map()

    addValidator(fieldName: string, validator: Validator): void {
      if (!this.validators.has(fieldName)) {
        this.validators.set(fieldName, [])
      }
      this.validators.get(fieldName)!.push(validator)
    }

    validate(data: Record<string, any>): ValidationResult {
      const errors: string[] = []

      for (const [fieldName, validators] of this.validators) {
        const value = data[fieldName]

        for (const validator of validators) {
          if (!validator.isValid(value)) {
            errors.push(`${fieldName}: ${validator.errorMessage}`)
          }
        }
      }

      return new ValidationResult(errors.length === 0, errors)
    }
  }
}

// 使用示例
export function createUserValidator(): Validation.FormValidator {
  const validator = new Validation.FormValidator()

  validator.addValidator('name', new Validation.RequiredValidator())
  validator.addValidator('name', new Validation.LengthValidator(2, 50))
  validator.addValidator('email', new Validation.RequiredValidator())
  validator.addValidator('email', new Validation.EmailValidator())
  validator.addValidator('password', new Validation.RequiredValidator())
  validator.addValidator('password', new Validation.PasswordValidator())

  return validator
}

实用工具类型

typescript
// utils/type-utils.ts - 实用工具类型
// 内置工具类型扩展

// 深度部分类型
export type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
}

// 深度必需类型
export type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P]
}

// 可空类型
export type Nullable<T> = T | null

// 可选可空类型
export type Optional<T> = T | undefined

// 数组元素类型
export type ArrayElement<T> = T extends (infer U)[] ? U : never

// 函数返回类型
export type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never

// 函数参数类型
export type ParametersOf<T> = T extends (...args: infer P) => any ? P : never

// 对象值类型
export type ValueOf<T> = T[keyof T]

// 键值对类型
export type KeyValuePair<T> = {
  [K in keyof T]: {
    key: K
    value: T[K]
  }
}[keyof T]

// 条件类型工具
export type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K
}[keyof T]

export type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>

// 字符串操作类型
export type Capitalize<S extends string> = S extends `${infer F}${infer R}`
  ? `${Uppercase<F>}${R}`
  : S

export type Uncapitalize<S extends string> = S extends `${infer F}${infer R}`
  ? `${Lowercase<F>}${R}`
  : S

// API响应类型工具
export type ApiSuccess<T> = {
  success: true
  data: T
  message?: string
}

export type ApiError = {
  success: false
  error: string
  code?: number
}

export type ApiResult<T> = ApiSuccess<T> | ApiError

// 状态机类型
export type StateMachine<S extends string, E extends string> = {
  currentState: S
  transition: (event: E) => S
  canTransition: (event: E) => boolean
}

// 事件类型
export type EventMap = {
  click: MouseEvent
  keydown: KeyboardEvent
  change: Event
  submit: SubmitEvent
}

export type EventHandler<K extends keyof EventMap> = (event: EventMap[K]) => void

// 组件Props类型工具
export type ComponentProps<T> = T extends React.ComponentType<infer P> ? P : never

// 异步类型工具
export type Awaited<T> = T extends Promise<infer U> ? U : T

// 递归类型
export type Flatten<T> = T extends (infer U)[]
  ? U extends (infer V)[]
    ? Flatten<V[]>
    : U
  : T

// 类型守卫工具
export function isString(value: unknown): value is string {
  return typeof value === 'string'
}

export function isNumber(value: unknown): value is number {
  return typeof value === 'number' && !isNaN(value)
}

export function isBoolean(value: unknown): value is boolean {
  return typeof value === 'boolean'
}

export function isArray<T>(value: unknown): value is T[] {
  return Array.isArray(value)
}

export function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
}

export function isFunction(value: unknown): value is Function {
  return typeof value === 'function'
}

export function isDefined<T>(value: T | undefined | null): value is T {
  return value !== undefined && value !== null
}

// 类型断言工具
export function assertIsString(value: unknown): asserts value is string {
  if (!isString(value)) {
    throw new Error('Expected string')
  }
}

export function assertIsNumber(value: unknown): asserts value is number {
  if (!isNumber(value)) {
    throw new Error('Expected number')
  }
}

// 使用示例
interface User {
  id: number
  name: string
  email: string
  profile: {
    avatar: string
    bio: string
  }
}

type PartialUser = DeepPartial<User>
type RequiredUser = DeepRequired<PartialUser>
type UserValues = ValueOf<User>
type UserKeyValue = KeyValuePair<User>

const apiResult: ApiResult<User> = {
  success: true,
  data: {
    id: 1,
    name: "John",
    email: "john@example.com",
    profile: {
      avatar: "avatar.jpg",
      bio: "Developer"
    }
  }
}

export {
  User,
  PartialUser,
  RequiredUser,
  UserValues,
  UserKeyValue,
  apiResult
}

📚 TypeScript基础学习总结与下一步规划

✅ 本节核心收获回顾

通过本节TypeScript基础深度教程的学习,你已经掌握:

  1. TypeScript核心概念理解:深入理解类型系统、编译原理和开发环境
  2. 基础类型系统应用:掌握原始类型、对象类型、数组和函数类型
  3. 高级类型特性运用:学会使用接口、泛型、联合类型和交叉类型
  4. 面向对象编程实践:掌握类、继承、抽象类和访问修饰符
  5. 模块系统管理:学会模块导入导出和命名空间应用
  6. 实用工具类型开发:掌握内置工具类型和自定义类型工具

🎯 TypeScript基础下一步

  1. 学习Vue TypeScript集成:掌握Vue 3 + TypeScript的开发模式
  2. 探索高级类型编程:学习条件类型、映射类型等高级特性
  3. 掌握装饰器应用:学习装饰器模式和元编程技术
  4. TypeScript工程化实践:学习配置优化和构建工具集成

🔗 相关学习资源

💪 实践建议

  1. 渐进式学习:从基础类型开始,逐步掌握高级特性
  2. 实践为主:每个概念都要通过代码实践加深理解
  3. 类型思维:培养类型安全的编程思维和习惯
  4. 工具配置:配置好IDE和开发工具,提升开发效率

🔍 常见问题FAQ

Q1: TypeScript会影响运行时性能吗?

A: 不会。TypeScript在编译时被转换为JavaScript,运行时没有额外开销。类型检查只在开发阶段进行。

Q2: 什么时候使用any类型?

A: 尽量避免使用any。只在迁移JavaScript代码、处理动态内容或第三方库没有类型定义时使用。优先考虑unknown类型。

Q3: 接口和类型别名有什么区别?

A: 接口支持声明合并和继承,更适合定义对象结构。类型别名更灵活,支持联合类型、条件类型等复杂类型。

Q4: 如何处理第三方库的类型问题?

A: 使用@types包、编写.d.ts声明文件或使用模块声明。优先查找官方或社区维护的类型定义。

Q5: 泛型什么时候使用?

A: 当需要类型参数化、提高代码复用性时使用泛型。常见场景包括工具函数、数据结构、API响应等。


🛠️ TypeScript最佳实践指南

开发环境配置

json
// tsconfig.json - TypeScript配置
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@/components/*": ["src/components/*"],
      "@/utils/*": ["src/utils/*"]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}

"TypeScript是现代前端开发的重要技术选择。通过静态类型检查、智能IDE支持和强大的类型系统,TypeScript能够显著提升代码质量和开发效率。掌握TypeScript基础是Vue.js高级开发的必备技能,为构建大型、可维护的应用奠定坚实基础!"