知海

全局插件模板

TypeScript-dev声明文件指南

全局插件模板

全局插件是一段全局代码,它会改变某个全局变量。对于修改了全局作用域的模块,它会增加出现运行时冲突的可能性。例如,有些库会向 Array.prototypeString.prototype 中增加新的函数。

识别全局插件

全局插件通常可以根据其文档来识别。你可能会看到如下示例:

js 复制代码
var x = 'hello, world';
// Creates new methods on built-in types
console.log(x.startsWithHello());

var y = [1, 2, 3];
// Creates new methods on built-in types
console.log(y.reverseAndSort());

这类代码库不需要通过 importrequire 引入即可直接使用,通常由 <script> 标签加载,并直接修改全局对象或内置类型。

模板结构

使用 global-plugin.d.ts 作为声明文件模板,其典型内容如下:

ts 复制代码
// Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
// Project: [~THE PROJECT NAME~]
// Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

/*~ This template shows how to write a global plugin. */

/*~ Write a declaration for the original type and add new members.
 *~ For example, this adds a 'toBinaryString' method with overloads to
 *~ the built-in number type.
 */
interface Number {
  toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string;

  toBinaryString(
    callback: MyLibrary.BinaryFormatCallback,
    opts?: MyLibrary.BinaryFormatOptions
  ): string;
}

/*~ If you need to declare several types, place them inside a namespace
 *~ to avoid adding too many things to the global namespace.
 */
declare namespace MyLibrary {
  type BinaryFormatCallback = (n: number) => string;
  interface BinaryFormatOptions {
    prefix?: string;
    padding: number;
  }
}

模板要点

  • 扩展全局接口:直接使用 interface 声明合并,为现有的全局类型(如 NumberStringArray)添加新成员。这是全局插件的核心工作。
  • 使用命名空间:将辅助类型放入 declare namespace 中,避免在全局作用域中创建过多名称,降低命名冲突风险。命名空间名称通常与代码库暴露的全局变量一致。
  • 头部注释:按照惯例填写库名、版本、项目地址和作者信息,便于维护和归属。

依赖处理

如果全局插件依赖于其他全局库,使用 /// <reference types="..." /> 指令:

ts 复制代码
/// <reference types="someLib" />

function getThing(): someLib.thing;

如果依赖的是 UMD 模块,同样使用 /// <reference types> 指令(因为全局插件本身不是模块,不能使用 import)。

防止命名冲突

虽然可以在全局作用域内定义许多类型,但不建议这样做。当工程中存在多个声明文件时,全局作用域的类型定义可能导致难以解决的命名冲突。

一个简单的规则是:使用代码库提供的全局变量来声明拥有命名空间的类型。例如,如果代码库提供了全局变量 MyLibrary,可以这样写:

ts 复制代码
declare namespace MyLibrary {
  interface KittySettings {}
}

而不是在顶层定义 interface CatsKittySettings {}。这样做既能保持代码清晰,也便于将来将代码库转换为 UMD 模块。

相关模板

如果目标库不是全局插件,而是以下类型,请参考对应的模板:

  • 模块:使用 module.d.tsmodule-class.d.tsmodule-function.d.ts 模板。
  • 模块插件:使用 module-plugin.d.ts 模板。
  • 修改了全局作用域的模块:使用 global-modifying-module.d.ts 模板。

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。