默认导出

默认导出是模块的主要导出,每个模块只能有一个默认导出。默认导出让模块的主要功能更加突出,导入时可以自定义名称。

基本语法

使用 export default 导出模块的主要成员。

export default class User {
  constructor(public name: string) {}
}

默认导出不需要名称,导入时可以自定义。

import User from "./user"

const user = new User("张三")
console.log(user.name)

默认导出函数

函数可以作为默认导出。

export default function greet(name: string): string {
  return `你好,${name}`
}

导入时可以自定义函数名称。

import sayHello from "./greet"

console.log(sayHello("张三"))

默认导出表达式

可以是任意表达式作为默认导出。

export default {
  name: "张三",
  age: 25,
  email: "zhangsan@example.com"
}

导入时获得整个对象。

import user from "./user"

console.log(user.name)
console.log(user.age)

默认导出与命名导出

模块可以同时有默认导出和命名导出。

export default class User {
  constructor(public name: string) {}
}

export function validateName(name: string): boolean {
  return name.length > 0
}

export const MAX_NAME_LENGTH = 50

导入时可以分别导入。

import User, { validateName, MAX_NAME_LENGTH } from "./user"

const user = new User("张三")
console.log(validateName(user.name))
console.log(MAX_NAME_LENGTH)

默认导入在前,命名导入在后。

默认导出类型

类型可以作为默认导出。

export default interface User {
  id: number
  name: string
  email: string
}

导入类型时使用默认导入语法。

import User from "./user"

const user: User = {
  id: 1,
  name: "张三",
  email: "zhangsan@example.com"
}

重导出默认导出

重新导出默认导出需要特殊语法。

export { default as User } from "./user"

或者重新导出并重命名。

export { default } from "./user"

默认导出的优缺点

默认导出的优点:

  • 导入时可以自定义名称
  • 突出模块的主要功能
  • 导入语法简洁

默认导出的缺点:

  • 导入名称不统一可能导致混淆
  • 自动导入时可能选择错误的名称
  • 不利于代码重构

最佳实践

推荐使用命名导出而不是默认导出。

export class User {
  constructor(public name: string) {}
}

export function validateName(name: string): boolean {
  return name.length > 0
}

命名导出的优点:

  • 导入名称一致,便于重构
  • 可以导出多个成员
  • 自动导入更可靠
import { User, validateName } from "./user"

const user = new User("张三")
console.log(validateName(user.name))

实际应用

默认导出常用于导出模块的主要类或函数。

export default class HttpClient {
  private baseUrl: string

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

  async get<T>(path: string): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`)
    return response.json()
  }

  async post<T>(path: string, data: any): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data)
    })
    return response.json()
  }
}

导入时可以自定义名称。

import ApiClient from "./http-client"

const client = new ApiClient("https://api.example.com")

async function main() {
  const users = await client.get("/users")
  console.log(users)
}

main()

小结

默认导出使用 export default 语法,每个模块只能有一个默认导出。默认导出导入时可以自定义名称,让模块的主要功能更加突出。模块可以同时有默认导出和命名导出。推荐优先使用命名导出,便于重构和维护。默认导出适用于导出模块的主要类或函数。