notes
  • Introduction
  • 语言
    • JS
      • JS原型到原型链
      • JS继承的实现
      • this对象
      • Promise基本概念
      • Promise实现
      • Promise实战
      • JS的EventLoop
      • JS容易出现误区的运算符
      • JS容易出现误区的操作符
      • JS深拷贝
      • JS节流与防抖
      • ES5实现原生/ES6方法
    • TS
      • 声明文件
      • 项目配置
    • CSS
      • CSS引入方式以及优先级计算
      • BFC神奇背后的原理-文摘
      • 回流reflow与重绘repaint
      • 三栏式布局
      • 垂直居中
      • 清除浮动的方法
      • 移动端适配方案
      • 纯CSS斜切角实现
      • CSS揭秘
      • 背景图片轮播
      • CSS绘制序列帧动画
      • transform实现一个多面体
    • HTML
  • ES6
  • Node.js
    • xxx
  • 前端框架
    • Vue.js
      • Vue双向数据绑定原理
      • Vue-Router原理及实现
    • React
    • AngularJS
  • 工程构建
    • Webpack
      • 01-webpack概述及背景
      • 03-webpack热更新原理
      • 04-splitChunks原理分析
      • 05-webpack工作流程
      • 07-webpack构建流程
      • 07-webpack构建流程
      • 10-webpack 如何进行性能分析
    • Gulp
    • Lint
      • ESLint
      • TSLint
    • Bable
  • 工程化
    • 模块化
    • 组件化
    • 规范化
      • 编码规范
    • 自动化
  • 运维
    • Nginx
    • GIT
    • CDN
    • VPS
    • DBA
  • 小程序
  • 跨端
  • 测试
  • 计算机技术
    • 计算机网络
      • 同源策略到前端跨域解决方案
      • TCP数据传输
      • TCP和UDP的区别
      • HTTP协议概述
      • HTTP缓存详解
      • HTTPS以及SSL建立过程
      • HTTPS的七个误解(译文)
      • cookie与Session机制区别以及Cookie SessionStorage LocalStorage异同
      • HTTP状态码Status
      • DNS原理入门
      • 网络攻击与防御
      • HTTP转发与重定向
      • 登录认证设计
    • 操作系统
      • shell脚本命令
    • Linux
      • Linux命令大全
      • vim命令
    • 浏览器
      • 浏览器内核、JS 引擎、页面呈现原理及其优化
      • 九种浏览器端缓存机制概览
      • 性能优化-网络请求方面
      • webkit解析CSS过程详解
  • 前端面试
    • 算法
Powered by GitBook
On this page
  • 支持语法
  • 声明文件应用场景
  • 书写声明文件
  • 全局变量的声明
  • npm包的声明
  • UMD库中的声明
  • 在 npm 包或 UMD 库中扩展全局变量
  • 声明模块插件
  • 发布声明文件
  • 将声明文件和源码放在一起
  • 参考
  1. 语言
  2. TS

声明文件

  • 从类型type角度分为:基本类型(string、number、boolean等)及其混合;复杂类型(class、function、object)及其混合(比如说又是class又是function)。

  • 从代码有效范围分为:全局变量、模块变量和又是全局变量又是模块变量的。

  • 从定义文件来说:自己写的.d.ts文件和扩展别人写的.d.ts文件。

支持语法

declare var             // 声明全局变量
declare function        // 声明全局方法
declare class           // 声明全局类
declare enum            // 声明全局枚举类型
declare namespace       // 声明(含有子属性的)全局对象
interface || type       // 声明全局类型
export                  // 导出变量
export namespace        // 导出(含有子属性的)对象
export default          // ES6 默认导出
export =                // commonjs 导出模块
export as namespace     // UMD 库声明全局变量
declare global          // 扩展全局变量
declare module          // 扩展模块
/// <reference />       // 三斜线指令

声明文件应用场景

主要是为了解决在ts中第三方组件库或者插件中,第三方库引用的问题。

例如,代码中用到了jQuery,需要到 .d.ts 文件中声明,不然TS语法会报找不到全局变量 jquery和$对象;

// shime-global.d.ts

declare var jQuery: (selector: string) => any;
declare var $: (selector: string) => any;

然后在改目录下所有ts中使用 jQuery, $ 对象是,ts便不会报错。

jQuery('#foo');

上例中,declare var 并没有真的定义一个变量,只是定义了全局变量 jQuery 的类型,仅仅会用于编译时的检查,在编译结果中会被删除。它编译结果是:

jQuery('#foo');

补充:上面声明文件为什么是.d.ts,这是ts模块解析规定的,先从.ts文件中查找,然后再查找 .d.ts文件中查找。

先让我们看看在工程中一般有哪些声明:

我们经常这样配置全局变量,如果第三方库没有声明,当前代码中没有定义的,都需要声明。

vue 模块的声明

// shims-vue.d.ts

declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

全局变量 模块

// shmie-global.d.ts

declare var window: Window;
declare var document: Document;

declare module "element-ui";

// ...

那么有些同学就要问了,我们用的很多npm,npm install之后,好像也没有声明,在ts中使用编译也没有报错啊。那是因为npm中已经声明了。

书写声明文件

当一个第三方库没有提供声明文件时,我们就需要自己书写声明文件了。

第三方库有以下几种使用场景

  • 全局变量:通过 标签引入第三方库,注入全局变量

  • npm 包:通过 import foo from 'foo' 导入,符合 ES6 模块规范

  • UMD 库:既可以通过 标签引入,又可以通过 import 导入

  • 直接扩展全局变量:通过 标签引入后,改变一个全局变量的结构

  • 在 npm 包或 UMD 库中扩展全局变量:引用 npm 包或 UMD 库后,改变一个全局变量的结构

  • 模块插件:通过 或 import 导入后,改变另一个模块的结构

全局变量的声明

全局变量的声明主要用以下几种

  • declare var 声明全局变量

  • declare function 声明全局方法

  • declare class 声明全局类

  • declare enum 声明全局枚举类型

  • declare namespace 声明(含有子属性的)全局对象

  • interface 和 type 声明全局类型

举个例子:声明一个class 对象 Animal

// Animal.d.ts 

declare class Animal {
    name: string;
    constructor(name: string);
    sayHi(): string;
}
// src/index.ts

let cat = new Animal('Tom');

npm包的声明

一般来说,npm 包的声明文件可能存在于两个地方:

  1. 与该 npm 包绑定在一起。判断依据是 package.json 中有 types 字段,或者有一个 index.d.ts 声明文件。这种模式不需要额外安装其他包,是最为推荐的,所以以后我们自己创建 npm 包的时候,最好也将声明文件与 npm 包绑定在一起。

  1. 发布到 @types 里。我们只需要尝试安装一下对应的 @types 包就知道是否存在该声明文件,安装命令是 npm install @types/foo --save-dev。这种模式一般是由于 npm 包的维护者没有提供声明文件,所以只能由其他人将声明文件发布到 @types 里了。

假如以上两种方式都没有找到对应的声明文件,那么我们就需要自己为它写声明文件了.

有两种方案,一种自己写@types/xxx,发布上去。另一个直接在工程目录下声明,建议新建一个目录types,声明文件放在types中

npm中声明和全局变量声明的区别

npm 包的声明文件与全局变量的声明文件有很大区别。在 npm 包的声明文件中,使用 declare 不再会声明一个全局变量,而只会在当前文件中声明一个局部变量。只有在声明文件中使用 export 导出,然后在使用方 import 导入后,才会应用到这些类型声明。

// 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;
}
// src/index.ts

import { name, getName, Animal, Directions, Options } from 'foo';

当然也可以混用

declare const name: string;
declare function getName(): string;
declare class Animal {
    constructor(name: string);
    sayHi(): string;
}
declare enum Directions {
    Up,
    Down,
    Left,
    Right
}
interface Options {
    data: any;
}

export { name, getName, Animal, Directions, Options };

上面 Axios就是这样做的。

UMD库中的声明

在 npm 包或 UMD 库中扩展全局变量

对于 npm 包或 UMD 库,如果导入此库之后会扩展全局变量,则需要使用另一种语法在声明文件中扩展全局变量的类型,那就是 declare global

// types/foo/index.d.ts

declare global {
    interface String {
        prependHello(): string;
    }
}

export {};


// src/index.ts
'bar'.prependHello();

声明模块插件

发布声明文件

两种方式

  • 将声明文件和源码放在一起

  • 发布到@types中

将声明文件和源码放在一起

  • 自动生成,tsc自动生成

  • 手动声明

如果是手动写的声明文件,那么需要满足以下条件之一,才能被正确的识别:

  • 给 package.json 中的 types 或 typings 字段指定一个类型声明文件地址

  • 在项目根目录下,编写一个 index.d.ts 文件

  • 针对入口文件(package.json 中的 main 字段指定的入口文件),编写一个同名不同后缀的 .d.ts 文件

{
    "name": "foo",
    "version": "1.0.0",
    "main": "lib/index.js",
    "types": "foo.d.ts",
}

如果没有指定types或typings,那么就会在根目录下寻找 index.d.ts 文件,将它视为此库的类型声明文件。

如果没有找到 index.d.ts 文件,那么就会寻找入口文件(package.json 中的 main 字段指定的入口文件)是否存在对应同名不同后缀的 .d.ts 文件。

如果还是不存在,那么就会寻找是否存在 lib/index.d.ts 文件。假如说连 lib/index.d.ts 都不存在的话,就会被认为是一个没有提供类型声明文件的库了。

参考

PreviousTSNext项目配置

Last updated 5 years ago

typescript-tutorial