编写声明文件是为 JavaScript 代码添加类型支持的重要技能。通过编写声明文件,可以让 JavaScript 库获得 TypeScript 的类型检查和智能提示。
声明文件的基本结构包含各种类型声明。
declare const version: string
declare function greet(name: string): string
declare class User {
constructor(name: string)
name: string
greet(): string
}
declare interface Config {
apiKey: string
baseUrl?: string
}
使用 declare const、declare let 或 declare var 声明变量。
declare const API_URL: string
declare let debug: boolean
declare var jQuery: (selector: string) => any
使用 declare function 声明函数。
declare function log(message: string): void
declare function fetch(
url: string,
options?: {
method?: string
headers?: Record<string, string>
body?: string
}
): Promise<Response>
函数声明支持重载。
declare function createElement(tag: "div"): HTMLDivElement
declare function createElement(tag: "span"): HTMLSpanElement
declare function createElement(tag: string): HTMLElement
使用 declare class 声明类。
declare class User {
constructor(name: string)
readonly name: string
private id: number
greet(): string
static create(name: string): User
}
类声明可以包含构造函数、属性、方法和静态成员。
使用 declare interface 或直接 interface 声明接口。
interface User {
id: number
name: string
email: string
}
interface Config {
apiKey: string
baseUrl?: string
timeout?: number
}
使用 declare type 或直接 type 声明类型别名。
type ID = string | number
type EventHandler = (event: Event) => void
type Status = "active" | "inactive" | "pending"
使用 declare enum 声明枚举。
declare enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING"
}
使用 declare module 声明模块。
declare module "my-library" {
export interface Config {
apiKey: string
debug?: boolean
}
export function init(config: Config): void
export function track(event: string, data?: any): void
const version: string
export default version
}
模块声明可以包含导出和默认导出。
使用 declare global 扩展全局命名空间。
declare global {
interface Window {
mySDK: {
init: (config: { apiKey: string }) => void
track: (event: string) => void
}
}
const API_URL: string
}
export {}
注意需要 export {} 使文件成为模块。
使用 declare namespace 声明命名空间。
declare namespace MyLib {
interface User {
id: number
name: string
}
function createUser(name: string): User
namespace Utils {
function formatDate(date: Date): string
}
}
使用 declare module 扩展现有模块。
import { User } from "my-library"
declare module "my-library" {
interface User {
age: number
email: string
}
}
扩展后的类型会合并到原有类型。
使用三斜线指令引用其他声明文件。
/// <reference path="./types/jquery.d.ts" />
/// <reference path="./types/lodash.d.ts" />
declare function $(selector: string): any
为一个简单的 SDK 编写声明文件。
declare module "analytics-sdk" {
export interface Config {
trackingId: string
debug?: boolean
bufferSize?: number
}
export interface Event {
name: string
timestamp: number
data?: Record<string, any>
}
export interface Analytics {
init(config: Config): void
track(eventName: string, data?: Record<string, any>): void
identify(userId: string, traits?: Record<string, any>): void
flush(): Promise<void>
}
const analytics: Analytics
export default analytics
}
使用时获得完整的类型支持。
import analytics, { Config, Event } from "analytics-sdk"
const config: Config = {
trackingId: "UA-XXXXX-Y",
debug: true,
bufferSize: 100
}
analytics.init(config)
analytics.track("page_view", { page: "/home" })
analytics.identify("user-123", { name: "张三" })
async function flushEvents() {
await analytics.flush()
}
flushEvents()
编写声明文件使用 declare 关键字声明各种类型。可以声明变量、函数、类、接口、类型别名、枚举等。declare module 用于声明模块,declare global 用于扩展全局命名空间,declare namespace 用于声明命名空间。声明文件让 JavaScript 库获得 TypeScript 的类型支持。