高质量TypeScript 类型定义的存储库。
您还可以阅读此自述文件的西班牙语、한국어、Русский、简体中文、葡萄牙语、意大利语、日本语和法语!
管理手册链接
Definely Typed 最近已更改为适当的pnpm
monorepo;您可能需要重新阅读本文档以了解此存储库中包布局的更改。
至少,您可能需要git clean -fdx
存储库(或 Windows 上的node ./scripts/clean-node-modules.js
)来清理node_modules
并运行pnpm install --filter .
安装工作区根目录。有关pnpm install
的更多信息,请参阅其他部分。
此部分跟踪存储库和发布过程的运行状况。这对于遇到 PR 和包任何问题的贡献者可能会有所帮助。
如果此处出现任何错误或上述任何内容失败,请在 TypeScript 社区 Discord 服务器上的 Definely Typed 频道中告知我们。
请参阅 TypeScript 手册。
这是首选方法。例如:
npm install --save-dev @types/node
要为作用域模块安装类型,请删除@
并在作用域后面添加双下划线。例如,要安装@babel/preset-env
的类型:
npm install --save-dev @types/babel__preset-env
然后编译器应该自动包含这些类型。如果您不使用模块,您可能需要添加types
引用:
/// <reference types="node" />
请参阅手册中的更多内容。
对于 npm 包“foo”,其类型将位于“@types/foo”。
如果您的包使用其package.json
中的types
或typings
键指定了类型,则 npm 注册表将显示该包具有可用的绑定,如下所示:
您可以像往常一样克隆整个存储库,但它很大并且包含大量类型包目录。这将需要一些时间来克隆,并且可能会变得不必要的笨拙。
对于仅包含与您相关的类型包的更易于管理的克隆,您可以使用 git 的sparse-checkout
和--filter
功能。这将减少克隆时间并提高 git 性能。
️ 这需要最低 git 版本 2.27.0,这可能比大多数机器上的默认版本更新。旧版本中提供了更复杂的过程,但本指南未涵盖。
git clone --sparse --filter=blob:none <forkedUrl>
--sparse
初始化稀疏签出文件,以便工作目录仅以存储库根目录中的文件开始。--filter=blob:none
将包含所有提交历史记录但排除文件,仅根据需要获取它们。git sparse-checkout add types/<type> types/<dependency-type> ...
pnpm test <package to test>
。当您创建 PR 来编辑现有包时, dt-bot
应@提及该包的所有者。如果没有,您可以在与 PR 相关的评论中自行执行此操作。
如果您是库作者并且您的包是用 TypeScript 编写的,请将生成的声明文件捆绑在您的包中,而不是发布到 Definely Typed。您还可以使用 JSDoc 进行类型注释,从 JavaScript 文件生成声明文件。
如果您要为 npm 包添加类型,请创建一个同名的目录。如果您要添加类型的包不在 npm 上,请确保您为其选择的名称不与 npm 上的包名称冲突。 (您可以使用npm info <my-package>
检查<my-package>
包是否存在。)
你的包应该有这样的结构:
文件 | 目的 |
---|---|
index.d.ts | 这包含包的类型。 |
<my-package>-tests.ts | 这包含测试打字的示例代码。此代码不会运行,但会进行类型检查。 |
tsconfig.json | 这允许您在包内运行tsc 。 |
.eslintrc.json | (很少)仅需要禁用为 eslint 编写的 lint 规则。 |
package.json | 包含包的元数据,包括其名称、版本和依赖项。 |
.npmignore | 指定要包含在包中的文件。 |
通过运行npx dts-gen --dt --name <my-package> --template module
生成这些文件。请参阅 dts-gen 中的所有选项。
如果除了index.d.ts
之外还有.d.ts
文件,请确保在index.d.ts
或测试中引用它们。
Definely Typed 成员会定期监视新的 PR,但请记住,其他 PR 的数量可能会减慢速度。
有关良好的示例包,请参阅 base64-js。
当包捆绑自己的类型时,应将类型从 Definely Typed 中删除以避免混淆。
您可以通过运行pnpm run not-needed <typingsPackageName> <asOfVersion> [<libraryName>]
来删除它。
<typingsPackageName>
:这是要删除的目录的名称。<asOfVersion>
:存根将使用此版本发布到@types/<typingsPackageName>
。应高于当前发布的任何版本,并且应为 npm 上<libraryName>
的版本。<libraryName>
:替换 Definely Typed 类型的 npm 包的名称。通常这与<typingsPackageName>
相同,在这种情况下您可以省略它。如果包从未出现在“Definitely Typed”上,则无需将其添加到notNeededPackages.json
中。
通过运行pnpm test <package to test>
测试您的更改,其中<package to test>
是您的包的名称。您需要从 DefinelyTyped 目录运行它,因为单个 package.json 不定义测试脚本。
此脚本使用 dtslint 针对您的 dts 文件运行 TypeScript 编译器。
准备好所有更改后,请使用pnpm run test-all
来查看更改如何影响其他模块。
attw
) 检查dtslint 包括来自 @arethetypeswrong/cli 的模块格式和package.json
配置检查。仅当可以在 npm 上找到与 SemVer 主要兼容的实现包以与 DefinelyTyped 包进行比较时,才会运行检查。 (将跳过在package.json
中标记为nonNpm
的 DefinitelyTyped 包。)
目前,许多软件包未通过attw
检查,需要修复。为了让我们取得增量进展,当attw.json
中的failingPackages
中列出包时,失败的attw
检查不会使dtslint
运行失败,但它们仍将在pnpm test my-package
输出中报告。如果修复该包,请将其从failingPackages
中删除,以便attw
检查可以开始失败的dtslint
运行。
attw
报告的所有问题都在输出中链接了文档。一些有助于避免问题的经验法则:
如果实现包在其package.json
中使用它们,DefinitelyTyped 包中的package.json
必须具有匹配的type
和exports
字段。例如,如果实现package.json
如下所示:
{
"name" : " my-package " ,
"version" : " 1.0.1 " ,
"type" : " module " ,
"main" : " dist/cjs/index.cjs " ,
"exports" : {
"." : {
"import" : " ./dist/esm/index.js " ,
"require" : " ./dist/cjs/index.cjs "
},
"./subpath" : {
"import" : " ./dist/esm/subpath.js " ,
"require" : " ./dist/cjs/subpath.cjs "
}
}
}
那么 DefinelyTyped package.json
应该类似于:
{
"name" : "@types/my-package" ,
"version" : "1.0.9999" ,
"type" : "module" ,
"types" : "index.d.ts" ,
"exports" : {
"." : {
"import" : "./index.d.ts" ,
"require" : "./index.d.cts"
} ,
"./subpath" : {
"import" : "./subpath.d.ts" ,
"require" : "./subpath.d.cts"
}
}
}
请注意,每个exports
路径都会被反映,并且每个 JavaScript 文件都有一个具有匹配文件扩展名的相应声明文件 - .d.ts
文件类型为.js
文件,而不是.mjs
或.cjs
文件!
当实现包使用module.exports = ...
时,DefinitelyTyped 包应该使用export =
,而不是export default
。 (或者,如果module.exports
只是命名属性的对象,DefiniteTyped 包可以使用一系列命名导出。)纠正此问题的最常见障碍是除了主导出之外如何导出类型的混乱。例如,假设这些类型错误地使用了export default
:
export interface Options {
// ...
}
export default function doSomething ( options : Options ) : void ;
将export default
更改为export =
会产生错误:
export interface Options {
// ...
}
declare function doSomething ( options : Options ) : void ;
export = doSomething ;
// ^^^^^^^^^^^^^^^^^
// Error: An export assignment cannot be used in a module with other exported elements.
要解决此问题,请将类型移动到与函数同名的命名空间内:
declare namespace doSomething {
export interface Options {
// ...
}
}
declare function doSomething ( options : doSomething . Options ) : void ;
export = doSomething ;
如果您需要帮助解决问题,请在 TypeScript 社区 Discord 服务器上的 DefinelyTyped 频道中提问。
如果您要为 npm 包添加类型,请创建一个同名的目录。如果您要添加类型的包不在 npm 上,请在package.json
中设置"nonNpm": true
,并确保您为其选择的名称不会与 npm 上的包名称冲突。 (您可以使用npm info <my-package>
检查<my-package>
包是否存在。)
在极少数情况下, nonNpm
可能会被设置为"conflict"
,这表明 npm 上有一个同名的包,但类型故意与该包冲突。对于定义环境(如@types/node
的包或虚拟包(如aws-lambda
来说,情况可能如此。尽可能避免使用"conflict"
。
<my-package>-tests.ts
应该有一个<my-package>-tests.ts
文件,它被视为您的测试文件,以及它导入的任何*.ts
文件。如果您在模块的文件夹中没有看到任何测试文件,请创建一个<my-package>-tests.ts
。这些文件用于验证从*.d.ts
文件导出的 API,这些文件作为@types/<my-package>
提供。他们自己不发货。
对*.d.ts
文件的更改应包括相应的*.ts
文件更改,该更改显示正在使用的 API,以便有人不会意外破坏您所依赖的代码。例如,对.d.ts
文件中的函数进行的更改向函数添加了新参数:
index.d.ts
:
- export function twoslash(body: string): string
+ export function twoslash(body: string, config?: { version: string }): string
<my-package>-tests.ts
:
import {twoslash} from "./"
// $ExpectType string
const result = twoslash("//")
+ // Handle options param
+ const resultWithOptions = twoslash("//", { version: "3.7" })
+ // When the param is incorrect
+ // @ts-expect-error
+ const resultWithOptions = twoslash("//", { })
如果您想知道从哪里开始测试代码,原始包的自述文件中的示例是一个很好的起点。
您可以从该存储库的根目录使用npm test <package to test>
验证您的更改,这会考虑更改的文件。
使用$ExpectType
断言表达式属于给定类型,使用@ts-expect-error
断言编译错误。示例:
// $ExpectType void
f ( 1 ) ;
// @ts-expect-error
f ( "one" ) ;
有关更多详细信息,请参阅 dtslint 自述文件。
.eslintrc.json
如果由于某种原因需要禁用 lint 规则,请针对特定行禁用它:
// eslint-disable-next-line no-const-enum
const enum Const {
One ,
}
const enum Enum { // eslint-disable-line no-const-enum
Two ,
}
您仍然可以使用 .eslintrc.json 禁用规则,但不应在新包中禁用。禁用整个包的规则会使审查变得更加困难。
tsconfig.json
tsconfig.json
应该将noImplicitAny
、 noImplicitThis
、 strictNullChecks
和strictFunctionTypes
设置为true
。
您可以编辑tsconfig.json
以添加新的测试文件、添加"target": "es6"
(异步函数所需)、添加到"lib"
或添加"jsx"
编译器选项。
esModuleInterop
/ allowSyntheticDefaultImports
TL;DR: tsconfig.json
中不允许使用esModuleInterop
和allowSyntheticDefaultImports
。
这些选项使得为 CJS 导出编写默认导入成为可能,从而对 Node 和某些 JS 捆绑器中的 CJS 和 ES 模块之间的内置互操作性进行建模:
// component.d.ts declare class Component { } // CJS export, modeling `module.exports = Component` in JS export = Component ; // index.d.ts // ESM default import, only allowed under 'esModuleInterop' or 'allowSyntheticDefaultExports' import Component from "./component" ;由于
index.d.ts
中导入的编译时有效性取决于特定的编译设置,而您的类型的用户不会继承这些设置,因此在DefinitelyTyped中使用此模式将迫使用户更改自己的编译设置,这可能是不正确的为了他们的运行时间。相反,您必须为 CJS 导出编写 CJS 导入,以确保广泛的、独立于配置的兼容性:// index.d.ts // CJS import, modeling `const Component = require("./component")` in JS import Component = require ( "./component" ) ;
package.json
该文件是必需的,并且应遵循以下模板:
{
"private" : true ,
"name" : "@types/PACKAGE-NAME" ,
"version" : "1.2.9999" ,
"projects" : [
"https://aframe.io/"
] ,
"dependencies" : {
"@types/DEPENDENCY-1" : "*" ,
"@types/DEPENDENCY-2" : "*"
} ,
"devDependencies" : {
"@types/PACKAGE-NAME" : "workspace:."
} ,
"owners" : [
{
"name" : "Your Name Here" ,
"githubUsername" : "ghost"
}
]
}
package.json
指定所有依赖项,包括其他@types
包。
您必须将非@types
依赖项添加到允许的外部依赖项列表中。皮卡迪就是一个很好的例子。这些添加内容得到了维护者的批准,这使我们有机会确保@types
包不依赖于恶意包。
如果实现包使用 ESM 并指定"type": "module"
,那么您应该修改 package.json 以匹配:
{
"type" : " module "
}
如果实现包的 package.json 中有exports
这也适用。
绝对类型化允许在package.json
中使用peerDependencies
。对等依赖关系可以帮助防止包管理器意外安装太新的版本或同一包的多个版本的情况。然而,对等依赖也有缺点;包管理器在对等依赖关系的处理上有所不同(例如, yarn
不会自动安装它们, npm
需要--legacy-peer-deps
来处理不匹配)。因此,引入新的对等依赖项的 PR 需要维护者批准,并且应仅限于特定情况。
一般来说,如果上游包对同一包(或其类型)具有对等依赖关系,则类型包应该仅具有对等依赖关系。例如,React 组件的 DT 包可以指定对@types/react@*
的对等依赖,因为使用者首先需要安装@types/react
才能使用 JSX。如果使用者在其项目中安装了@types/react@16
,但 npm 上有更新版本的@types/react
,则对等依赖关系可能会帮助包管理器选择@types/react@16
而不是该较新版本。类似地, chai-as-promised
对chai
有对等依赖,因此@types/chai-as-promised
应该对@types/chai
有对等依赖。
在某些情况下,上游包对类型包没有对等依赖关系,但对等依赖关系仍然是合适的。这些通常是上游包扩展另一个包并假设它存在的情况,因此应该在扩展另一个包时声明对等依赖关系,但没有。例如, chai-match-pattern
扩展了chai
,但没有声明对chai
对等依赖关系,但需要它才能发挥作用。 @types/chai-match-pattern
应该对@types/chai
具有对等依赖关系。
如果由于上游包中的常规依赖关系,一个包只是将另一个包的类型公开作为其 API 的一部分,则它不应该使用对等依赖关系。例如, express
的"dependencies"
中有qs
。用户安装express
时,不需要手动安装qs
。同样, @types/express
在其"dependencies"
中有@types/qs
。将@types/qs
声明为@types/express
的对等依赖项是不正确的,因为这需要一些下游消费者手动安装@types/qs
。
.npmignore
该文件定义了每个@types
包中要包含哪些文件。它必须采取特定的形式。对于存储库中只有一个版本的软件包:
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
这就是说“忽略所有文件,但不要忽略任何声明文件”。对于存储库中具有多个版本的软件包,“最新”版本(位于顶层)应包含类似以下内容的内容:
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
/ v15 /
/ v16 /
/ v17 /
这与之前的.npmignore
相同,但忽略每个版本化的子目录。
如果此文件包含错误内容并提供预期值,CI 将失败。无论该文件包含什么内容,发布者都只会发布声明文件。
pnpm dprint fmt -- 'path/to/package/**/*.ts'
。.vscode/settings.template.json
(或其他编辑器的等效项)在保存时使用 VS Code dprint 扩展进行格式化function sum(nums: number[]): number
:如果函数不写入其参数,则使用ReadonlyArray
。interface Foo { new(): Foo; }
:这定义了一种可新建的对象类型。您可能想要declare class Foo { constructor(); }
。const Class: { new(): IClass; }
: 更喜欢使用类声明class Class { constructor(); }
不是新的常量。getMeAT<T>(): T
:如果类型参数没有出现在任何参数的类型中,那么你并没有真正拥有泛型函数,你只是有一个伪装的类型断言。更喜欢使用真实类型断言,例如getMeAT() as number
。可接受类型参数的示例: function id<T>(value: T): T;
。不可接受的示例: function parseJson<T>(json: string): T;
。例外: new Map<string, number>()
可以。Function
和Object
类型几乎从来都不是一个好主意。在 99% 的情况下,可以指定更具体的类型。例如,函数的(x: number) => number
和对象的{ x: number, y: number }
。如果类型完全不确定, any
是正确的选择,而不是Object
。如果关于该类型的唯一已知事实是它是某个对象,请使用类型object
,而不是Object
或{ [key: string]: any }
。var foo: string | any
:当在联合类型中使用any
时,结果类型仍然是any
。因此,虽然此类型注释的string
部分可能看起来很有用,但实际上它比简单地使用any
不提供额外的类型检查。根据意图,可接受的替代方案可以是any
、 string
或string | object
。TL;DR:不要修改
.github/CODEOWNERS
,始终修改package.json
中的所有者列表。
DT 有“定义所有者”的概念,即想要维护特定模块类型质量的人。
要将您自己添加为定义所有者,请修改package.json
中的owners
数组:
"owners" : [
{
"name" : " Some Person " ,
"githubUsername" : " somebody "
},
{
"name" : " Some Corp " ,
"url" : " https://example.org "
}
]
请注意,此列表不用于提供贡献;它仅用于管理公关评论。
定义所有者每周一次同步到文件 .github/CODEOWNERS,这是我们的事实来源。
Definely Typed 是 GitHub 上最活跃的存储库之一。您可能想知道这个项目是如何产生的。 @johnnyreilly 写了《Definitely Typed》的历史。它讲述了 Definely Typed 早期的故事,从 @borisyankov 创建的存储库,到它成为 TypeScript 生态系统的关键部分。您可以在这里阅读Definitely Typed 的故事。
@types
包之间到底有什么关系?感谢 DefinelyTyped-tools, master
分支会自动发布到 npm 上的@types
范围。
这取决于情况,但大多数拉取请求将在一周内合并。有些 PR 可以由模块所有者合并,并且合并速度更快。大致:
仅更改模块类型并具有相应测试更改的 PR 合并速度会更快
已被定义的package.json
中列出的所有者批准的 PR 通常合并得更快;新定义的 PR 将需要更多时间,因为它们需要维护者进行更多审查。每个 PR 在合并之前都会由 TypeScript 或 Definely Typed 团队成员进行审核,因此请耐心等待,人为因素可能会导致延迟。检查新拉取请求状态板以查看维护人员处理开放 PR 时的进度。
对于非常流行的模块的更改,例如 Node/Express/Jest 在 npm 上每周有数百万次下载,对贡献的要求有点高。这些项目的变化可能会产生巨大的生态系统影响,因此我们非常谨慎地对待它们的变化。这些模块需要 DT 维护者的签字和模块所有者的热情支持。通过这个的门槛可能相当高,而且 PR 通常会因为没有冠军而变得陈旧。如果您发现没有人做出承诺,请尝试让您的公关焦点较小。
@types
npm 包什么时候更新?npm 包应该在一小时内更新。如果已经超过一个小时,请在 TypeScript 社区 Discord 服务器上的 Definely Typed 频道上提及 PR 编号,当前维护者将找到正确的团队成员进行调查。
<reference types="" />
还是导入?如果您引用的模块是一个模块(使用export
),请使用导入。如果您引用的模块是环境模块(使用declare module
)或只是声明全局变量,请使用<reference types="" />
。
tsconfig.json
缺少"noImplicitAny": true
、 "noImplicitThis": true
或"strictNullChecks": true
。那么他们错了,我们还没有注意到。您可以通过提交拉取请求来修复它们。
是的,使用 dprint。我们建议您的编辑器使用 dprint 扩展。
或者,您可以启用 git hook,它会自动格式化您的代码。运行pnpm run setup-hooks
。然后,当您提交时, dprint fmt
命令将在更改的文件上执行。如果您利用部分克隆,请确保在运行setup-hooks
脚本之前调用git sparse-checkout add .husky
来检查 git hooks。
拉取请求不需要合并正确的格式。任何未格式化的代码在合并后都会自动重新格式化。
如果您是 VS Code 用户,我们建议将
.vscode/settings.template.json
文件复制到.vscode/settings.json
。该模板将 dprint VS Code 扩展设置为存储库中的默认格式化程序。
以下是当前请求的定义。
如果类型是 Web 标准的一部分,则应将它们贡献给 TypeScript-DOM-lib-generator,以便它们可以成为默认lib.dom.d.ts
的一部分。
如果根本没有源 JavaScript 代码,例如,如果您正在编写帮助程序类型或规范类型,则您应该自己发布类型,而不是在 Definely Typed 上发布。因为它们旨在为现有 JavaScript 代码提供类型,所以@types
包并不意味着直接导入。也就是说,您不应该创建一个像import type { ... } from "@types/foo"
这样使用的绝对类型包。当没有安装foo
时,您也不应该期望编写import type { ... } from "foo"
。
这与为仅浏览器的 JavaScript 库提供类型或为整个环境(如 Node、Bun 等)提供类型不同。在那里,类型要么隐式解析,要么使用/// <references types="foo" />
。
有些包(例如 chai-http)会导出函数。
使用 ES6 风格导入以import * as foo from "foo";
导致错误:
错误 TS2497:模块“foo”解析为非模块实体,无法使用此构造导入。
可以通过将函数声明与同名的空命名空间合并来抑制此错误,但不鼓励这种做法。这是关于这个问题的一个经常被引用的 Stack Overflow 答案。
使用import foo = require("foo");
导入模块更合适。句法。尽管如此,如果您想使用默认导入,例如import foo from "foo";
你有两个选择:
--allowSyntheticDefaultImports
编译器选项。--esModuleInterop
编译器选项。 export =
,但我更喜欢使用默认导入。我可以将export =
更改为export default
吗?与上一个问题一样,请参阅使用--allowSyntheticDefaultImports
或--esModuleInterop
编译器选项。
如果类型定义准确,请勿更改。对于 npm 包,如果node -p 'require("foo")'
用于导入模块,则export =
是准确的;如果node -p 'require("foo").default'
用于导入模块,则export default
是准确的。
然后,您将通过在package.json
中指定"minimumTypeScriptVersion": "XY"
来设置支持的最低版本。
但是,如果您的项目需要同时维护与 3.7 及更高版本兼容的类型以及与 3.6 或更低版本兼容的类型,则需要使用typesVersions
功能。您可以在官方 TypeScript 文档中找到此功能的详细说明。
这是一个帮助您入门的简短示例:
您必须将typesVersions
添加到package.json
:
{
"private" : true ,
"types" : " index " ,
"typesVersions" : {
"<=3.6" : { "*" : [ " ts3.6/* " ] }
}
}
在 types 目录中创建typesVersions
字段中提到的子目录(本例中为ts3.6/
)。 ts3.6/
将支持 TypeScript 3.6 及更低版本,因此请复制现有类型和测试。
返回包的根目录,添加您要使用的 TypeScript 3.7 功能。当人们安装该包时,TypeScript 3.6 及更低版本将从ts3.6/index.d.ts
开始,而 TypeScript 3.7 及更高版本将从index.d.ts
开始。
你可以看看蓝鸟的例子。
这可能属于 TypeScript-DOM-lib-generator。请参阅那里的指南。如果该标准仍然是草案,那么它就属于这里。使用以dom-
开头的名称,并包含指向标准的链接作为package.json
中的“Project”链接。当它退出草稿模式时,我们可能会将其从 Definely Typed 中删除,并弃用相关的@types
包。
注意:本节中的讨论假设您熟悉语义版本控制
每个 Definely Typed 包在发布到 npm 时都会进行版本控制。 DefinitiveTyped-tools(将@types
包发布到npm的工具)将使用package.json
中列出的major.minor.9999
版本号来设置声明包的版本。例如,以下是撰写本文时 Node 版本20.8.x
的类型声明的前几行:
{
"private" : true ,
"name" : " @types/node " ,
"version" : " 20.8.9999 "
}
由于版本列出为20.8.9999
,因此@types/node
包的 npm 版本也将为20.8.x
。请注意, package.json
中的版本应仅包含major.minor
版本(例如10.12
),后跟.9999
。这是因为库包和类型声明包之间只有主要和次要版本号是对齐的。 ( .9999
是为了确保本地开发过程中本地@types
包始终是最新的。)类型声明包的补丁版本号(例如20.8.0
中的.0
)被Definitely Typed初始化为零,并且每次都会递增一个新的@types/node
包发布到 npm,用于相应库的相同主要/次要版本。
有时类型声明包版本和库包版本可能会不同步。以下是一些常见原因,按给图书馆用户带来不便的程度排序。只有最后一种情况通常是有问题的。
@types
包之间的版本相对应,那么npm update
通常应该可以正常工作。 ❗ 如果您要更新库的类型声明,请始终在package.json
中设置major.minor
版本以匹配您正在记录的库版本! ❗
语义版本控制要求具有重大更改的版本必须增加主版本号。例如,在3.5.8
版本之后删除公开导出函数的库必须在下一个版本中将其版本提升到4.0.0
。此外,当库的4.0.0
版本发布时,它的 Definely Typed 类型声明包也应该更新到4.0.0
,包括对库 API 的任何重大更改。
许多库都有大量的开发人员安装基础(包括使用该库作为依赖项的其他软件包的维护人员),他们不会立即迁移到具有重大更改的新版本,因为维护人员可能需要几个月的时间才能重写代码以适应新版本。与此同时,旧库版本的用户仍然可能希望更新旧版本的类型声明。
如果您打算继续更新旧版本的库类型声明,您可以创建一个以当前(即将成为“旧”)版本命名的新子文件夹(例如/v2/
),并将现有文件从当前版本复制到其中。
创建新版本文件夹时,确保package.json
的version字段已更新;只要需要, pnpm
就会自动解析到此版本化包。如果存储库中的其他包需要依赖于这个新版本,请确保它们的package.json
也被更新。
例如,如果我们创建types/history/v2
,它的package.json
将如下所示:
{
"private" : true ,
"name" : " @types/history " ,
"version" : " 2.4.9999 "
}
另一个包可以通过指定来选择此版本:
{
"private" : true ,
"name" : " @types/browser-sync " ,
"version" : " 2.26.9999 " ,
"dependencies" : {
"@types/history" : " ^2 "
}
}
另外, /// <reference types=".." />
不适用于路径映射,因此依赖项必须使用import
。
@types
包总是键入相同版本的包,因此@types/[email protected]
代表[email protected]
。因此,所有更改,无论是否破坏,都会作为补丁修订版发布,除非与主要/次要版本一起更改目标包版本(无论是否巧合)。
当谈到重大变更时,DT 维护者会考虑软件包的受欢迎程度、提议的重大变更的优点、用户修复代码所需的工作量,以及变更是否可以合理地推迟到可以同步为止。上游库的重大变化。
TypeScript 手册包含有关编写定义的优秀一般信息,以及此示例定义文件,该文件展示了如何使用 ES6 样式模块语法创建定义,同时还指定可用于全局范围的对象。这项技术在big.js
的定义中得到了实际演示,big.js 是一个可以通过网页上的脚本标记全局加载或通过 require 或 ES6 样式导入导入的库。
要测试您的定义在全局引用或作为导入模块时如何使用,请创建一个test
文件夹并在其中放置两个测试文件。将一个命名YourLibraryName-global.test.ts
,将另一个命名YourLibraryName-module.test.ts
。全局测试文件应根据在网页上加载的脚本中的使用方式来执行定义,其中该库在全局范围内可用 - 在这种情况下,您不应指定 import 语句。模块测试文件应根据导入时的使用方式(包括import
语句)来执行定义。如果您在tsconfig.json
文件中指定files
属性,请确保包含两个测试文件。 big.js
定义中也提供了一个实际示例。
请注意,不需要在每个测试文件中充分执行定义 - 仅测试全局测试文件上的全球访问元素并在模块测试文件中完全遵守定义,反之亦然。
示波器软件包的类型@foo/bar
应在types/foo__bar
中使用。请注意双重下划线。
该项目已获得 MIT 许可。
定义文件上的版权是每个定义文件开头列出的每个贡献者的分别。