TypeScript学习笔记(⼋)-声明⽂件
本篇将介绍TypeScript的声明⽂件,并简单演⽰⼀下如何编写和使⽤声明⽂件。本篇也是的最后⼀篇。
⼀、声明⽂件简介
TypeScript作为JavaScript的超集,在开发过程中不可避免要引⽤其他第三⽅的JavaScript的库。虽然通过直接引⽤可以调⽤库的类和⽅法,但是却⽆法使⽤TypeScript诸如类型检查等特性功能。为了解决这个问题,需要将这些库⾥的函数和⽅法体去掉后只保留导出类型声明,⽽产⽣了⼀个描述JavaScript库和模块信息的声明⽂件。通过引⽤这个声明⽂件,就可以借⽤TypeScript的各种特性来使⽤库⽂件了。
⼆、常见库的结构
有以下⼏种:全局库、CommonJS、AMD、UMD
全局库:
早期版本的jQuery就是使⽤了全局库的使⽤⽅式:
1 (function( window, undefined ) {
2var jQuery = function( selector, context ) {
3return new jQuery.fn.init( selector, context, rootjQuery );
4    }
5
6// ......
7
8    window.jQuery = window.$ = jQuery;
9 })(window);
通常会看到:
顶级的声明是var或者function
有 window 或者 document 这些DOM对象存在
对象⼀般会赋值到 window 上
CommonJS
NodeJs模块化采⽤的规范,声明和使⽤⽅式如下:
1// 模块定义⽂件
dule_name = {};
3
4// 模块调⽤⽂件
5var module = require('模块定义⽂件名');
通常会看到:
赋值给 exports 或者 ports
⽆条件调⽤ require
AMD
前端框架普遍采⽤的模块化的规范,声明和使⽤⽅式如下:
1// 定义模块
2 define('模块名', ['jquery', ...], function($){
3// ......
4 });
5
6// 调⽤模块
7 require(['模块名'], function(module) {
8// ......
9 });
通常会看到:
⽆条件调⽤ define 或者 require
UMD
为了能同时⽀持上述所有风格的库声明⽅式,就有了通⽤模块规范(UMD)。⼀般会有下⾯这种声明⽅式:
1// moment.js
2 (function (global, factory) {
3typeof exports === 'object' && typeof module !== 'undefined' ? ports = factory() :
4typeof define === 'function' && define.amd ? define(factory) :
5    = factory()
6 }(this, function() {
7function hooks() {
8// ......
9    }
10
11// ......
12return hooks;
三角函数公式大全表格120 135 150 18013 }));
通常会看到:
在⽂件顶端会有⼀⼤串typeof XXX 的判断
同时有 exports 、 define 这种关键词
通过识别库的结构,采⽤不⽤的声明⽅式来编写声明⽂件。
三、如何编写声明⽂件
linq.js实现了在JavaScript⾥使⽤Linq语法,在C#有的Linq⽅法,在它⾥⾯⼏乎都有。下⾯将在nodejs环境⾥演⽰如何编写和使⽤linq.js 的⼀个简单的声明⽂件。
1. 创建⼀个nodejs⼯程,并通过 npm install linq --save 下载插件包。⼯程结构如下所⽰:
1 {
2  "name": "tstest",
3  "version": "1.0.0",
4  "description": "",
5  "main": "index.js",
6  "scripts": {
7    "test": "echo \"Error: no test specified\" && exit 1",
8    "start": "node dist\\main.js"
9  },
10  "author": "",
11  "license": "ISC",
12  "dependencies": {
13    "linq": "^3.0.5"
14  }
15 }
package.json
1 {
2    "compilerOptions": {
3        "target": "es5",
4        "noImplicitAny": false,
5        "module": "commonjs",
6        "removeComments": true,
7        "sourceMap": false,
8        "outDir": "dist"
9    }
10 }
tsconfig.json
2. 在src⽬录下新建⽂件linq.d.ts
1 interface IEnumerator {
2    current: () => any;
3    moveNext: () => void;
4    dispose: () => void;
5 }
phpstudy为什么打不开
6
自建站怎么做
7 interface Enumerable {
8    getEnumerator: () => IEnumerator;
9    from: (obj: any) => Enumerable;
10    where: (predicate: string | ((x: any) => boolean)) => Enumerable;
11    toArray: () => Array<any>;
12 }
13
14 declare let linq: Enumerable;
15
16 declare module 'linq' {
17    export = linq;
18 }
3. 还是在src⽬录下新建⽂件main.ts
百度站长推送工具
1/// <reference path="linq.d.ts" />
2
3 import * as Enumerable from 'linq';
4
5 let result1 = Enumerable.from([1, 2, 3]).where('$>1').toArray();
6 console.log(`result1 is ${result1}`);
7
8 let result2 = Enumerable.from([1, 2, 3]).where(x => { return x > 2; }).toArray();
9 console.log(`result2 is ${result2}`);
4. 按下快捷键 Ctrl+Shift+B 编译main.ts⽂件到dist⽬录,⽣成main.js⽂件
1 "use strict";
2var Enumerable = require('linq');
3var result1 = Enumerable.from([1, 2, 3]).where('$>1').toArray();
4 console.log("result1 is " + result1);
5var result2 = Enumerable.from([1, 2, 3]).where(function (x) { return x > 2; }).toArray();
在windows中 回收站是6 console.log("result2 is " + result2);
在控制台执⾏命令 npm run start ,查看输出结果
从这个例⼦⾥可以看出,声明⽂件linq.d.ts⾥只定义了linq的类型和⽅法名称,在这⾥我称之为“⾻架”。在引⽤了声明⽂件后,即可以通过智能感知和强类型检查等特性使⽤linq模块。编译时会根据配置⽂件指定的模块标准( "module": "commonjs" )⽣成对应的⽂件。因为这个例⼦的运⾏环境是nodejs,所以采⽤commonjs标准。
jquery下载文件请求如果是在前端使⽤,则要采⽤AMD标准。下⾯是采⽤这个标准后编译⽣成的⽂件:
1 define(["require", "exports", 'linq'], function (require, exports, Enumerable) {
2    "use strict";
3var result1 = Enumerable.from([1, 2, 3]).where('$>1').toArray();
4    console.log("result1 is " + result1);
5var result2 = Enumerable.from([1, 2, 3]).where(function (x) { return x > 2; }).toArray();
6    console.log("result2 is " + result2);
7 });
linq模块也⽀持全局库的引⽤⽅式。通过修改linq.d.ts,⽀持全局库引⽤
1 interface IEnumerator {
2    current: () => any;
3    moveNext: () => void;
4    dispose: () => void;
5 }
6
7 interface Enumerable {
8    getEnumerator: () => IEnumerator;
9    from: (obj: any) => Enumerable;
10    where: (predicate: string | ((x: any) => boolean)) => Enumerable;
11    toArray: () => Array<any>;
12 }
13
14 declare let linq: Enumerable;
15
16// 全局库引⽤
17 export as namespace Enumerable;
18 export = linq;
main.ts调⽤⽅式也要修改
1/// <reference path="linq.d.ts" />
2
3 let result1 = Enumerable.from([1, 2, 3]).where('$>1').toArray();
4 console.log(`result1 is ${result1}`);
5
6 let result2 = Enumerable.from([1, 2, 3]).where(x => { return x > 2; }).toArray();
7 console.log(`result2 is ${result2}`);
编译⽣成的main.js
1var result1 = Enumerable.from([1, 2, 3]).where('$>1').toArray();
2 console.log("result1 is " + result1);
3var result2 = Enumerable.from([1, 2, 3]).where(function (x) { return x > 2; }).toArray();
4 console.log("result2 is " + result2);
四、声明⽂件下载
TypeScript2.0⽀持通过npm下载常⽤的模块的声明⽂件,下⾯借⽤async模块简单演⽰⼀下如何引⽤和使⽤常⽤模块的声明⽂件。
1. 通过 npm install async --save 下载async模块
2. 使⽤ npm install @types/async --save-dev 下载async模块的声明⽂件。下载完成后会在⼯程的node_modules⽂件夹下⽣成存放声明
⽂件的⽂件夹
3. main.ts引⽤声明⽂件
1/// <reference types="async" />
2 import * as async from 'async';
3
4// 并⾏执⾏⽅法
5 async.parallel([
6    cb => { cb(null, 1); },
7    cb => { cb(null, 2); },
8    cb => { cb(null, 3); },
9 ], (err, results) => {
10    console.log(`results is ${results}`);
11 });
这⾥的引⽤⽅式和上⾯的例⼦略有不同。上⾯的例⼦是⽤ref注释将⽂件名引⽤进来,通过npm下载的声明⽂件则是引⽤类型名称(/// <reference types="async" />)
4. 编译之后⽣成main.js,控制台执⾏查看结果
1 "use strict";
2var async = require('async');
3 async.parallel([
4function (cb) { cb(null, 1); },
5function (cb) { cb(null, 2); },
6function (cb) { cb(null, 3); },
7 ], function (err, results) {
8    console.log("results is " + results);
9 });
main.js

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。