既包含类型信息又可执行代码。可以被编译成 .js 文件。
只包含类型信息的类型声明文件。不会生成 .js 文件,仅用于提供类型信息。
.ts是implementation(代码实现文件).d.ts是declaration(类型声明文件)
ts的代码最后会编译成 .js 的 js 代码供他人使用,这个时候,类型信息就丢失了。
所以 ts 编译器会自动根据 .ts 中的信息,生成对外的 .d.ts 文件,和生成的 js 文件搭配使用。
其中,js 文件是给运行引擎用的,而 .d.ts 文件是给 IDE(智能编辑器)写代码时参考用的。
如果要为 JS 库提供类型信息,要用 .d.ts 文件。
npm install @types/jquery --save-dev
与NPM一同发布,package.json 中有 types 字段,或者有一个 index.d.ts 声明文件
创建一个 node_modules/@types/foo/index.d.ts
文件,存放foo
模块的声明文件。不太建议用这种方案,一般只用作临时测试。
创建一个 types
目录,专门用来管理自己写的声明文件,将 foo
的声明文件放到 types/foo/index.d.ts
中。这种方式需要配置下tsconfig.json
中的 paths
和 baseUrl
字段。
/path/to/project
├── src
| └── index.ts
├── types
| └── foo
| └── index.d.ts
└── tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"baseUrl": "./",
"paths": {
"*": ["types/*"]
}
}
}
declare let jQuery: (selector: string) => any;
declare function jQuery(selector: string): any;
declare class Animal {
name: string;
constructor(name: string);
sayHi(): string;
}
declare enum Directions {
Up,
Down,
Left,
Right
}
declare namespace jQuery {
function ajax(url: string, settings?: any): void;
namespace fn {
function extend(object: any): void;
}
}
// types/foo/index.d.ts
export const name: string;
export function getName(): string;
export class Animal {
constructor(name: string);
sayHi(): string;
}
export enum Directions {
Up,
Down,
Left,
Right
}
export interface Options {
data: any;
}
export namespace foo {
const name: string;
namespace bar {
function baz(): string;
}
}
// types/foo/index.d.ts
// function、class 和 interface 可以直接默认导出,其他的变量需要先定义出来,再默认导出
export default function foo(): string;
export default Directions;
declare enum Directions {
Up,
Down,
Left,
Right
}
// types/foo/index.d.ts
declare const name: string;
declare function getName(): string;
declare class Animal {
constructor(name: string);
sayHi(): string;
}
declare enum Directions {
Up,
Down,
Left,
Right
}
// interface 前是不需要 declare
interface Options {
data: any;
}
export { name, getName, Animal, Directions, Options };
注:
.d.ts文件顶级声明declare最好不要跟export同级使用,不然在其他ts引用这个.d.ts的内容的时候,就需要手动import导入了
.d.ts文件里如果顶级声明不用export的话,declare和直接写type、interface效果是一样的,在其他地方都可以直接引用
// types/foo-bar.d.ts
declare module 'foo' {
export interface Foo {
foo: string;
}
}
declare module 'bar' {
export function bar(): string;
}
// src/index.ts
import { Foo } from 'foo';
import * as bar from 'bar';
let f: Foo;
bar.bar();
书写一个全局变量的声明文件
依赖一个全局变量的声明文件
在声明文件中使用///
头,来引入依赖的其它声明。
// types/jquery-plugin/index.d.ts
///
declare function foo(options: JQuery.AjaxSettings): string;
--declaration(简写 -d)
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"outDir": "lib",
"declaration": true,
}
}
发布到社区
@types 是统一由 DefinitelyTyped 管理的。要将声明文件发布到 @types 下,就需要给 DefinitelyTyped 创建一个 pull-request,其中包含了类型声明文件,测试代码,以及 tsconfig.json 等。
与源码一起(依次查找*.d.ts)
///
///
///
declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production' | 'test';
readonly PUBLIC_URL: string;
}
}
declare module '*.avif' {
const src: string;
export default src;
}
declare module '*.bmp' {
const src: string;
export default src;
}
declare module '*.gif' {
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
}
declare module '*.webp' {
const src: string;
export default src;
}
declare module '*.svg' {
import * as React from 'react';
export const ReactComponent: React.FunctionComponent<React.SVGProps<
SVGSVGElement
> & { title?: string }>;
const src: string;
export default src;
}
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.sass' {
const classes: { readonly [key: string]: string };
export default classes;
}