代码库的不同类型
不同的类型的代码库,需要编写不同形式的.d.ts
文件,
目前总共有以下几种流行的代码库类型:
(1)全局代码库(Global Libraries)
(2)模块库(Modular Libraries)
(3)UMD
(4)模块库或UMD的插件(Module Plugin or UMD Plugin)
(5)全局代码库的插件(Global Plugin)
(6)全局代码库的修改模块(Global-modifying Modules)
全局代码库(Global Libraries)
1. 代码库的表现形式
全局代码库,会导出名字到全局对象的属性上,例如,
// 全局声明function createGreeting(s) { return "Hello, " + s; }// 直接给全局变量赋值window.createGreeting = function(s) { return "Hello, " + s; }
2. 代码库的使用方式
如果我们依赖一个全局代码库,TypeScript要求在用户代码中如下声明它,
/// <reference types="someLib" />function getThing(): someLib.thing;
即,需要增加/// <reference types="..." />
指令,以找到相关的.d.ts
文件。
3. .d.ts文件的编写方式
全局代码库的.d.ts
文件编写方式如下,(官网例子:global.d.ts)
// 如果全局代码库,导出了一个名为myLib的函数// 例如,window.myLib(xxx)declare function myLib(a: string): string;declare function myLib(a: number): number;// 如果全局代码库,导出了一个自定义类型// 例如,var x: myLibinterface myLib { name: string; length: number; extras?: string[]; }// 如果全局代码库,导出了一个对象// 例如,window.myLib.timeout, window.myLib.version, ...declare namespace myLib { // window.myLib.timeout let timeout: number; // window.myLib.version const version: string; // window.myLib.Cat class Cat { constructor(n: number); readonly age: number; purr(): void; } // var x: window.myLib.CatSettings interface CatSettings { weight: number; name: string; tailLength?: number; } // var x: window.myLib.VetID type VetID = string | number; // window.myLib.checkCat(xxx) function checkCat(c: Cat, s?: VetID); }
模块库(Modular Libraries)
1. 代码库的表现形式
模块库指的是,类似CommonJS,AMD(RequireJS),ES6 module这样的代码组织方式,
// CommonJSvar fs = require("fs");// TypeScript 或 ES6import fs = require("fs");// AMDdefine(..., ['someLib'], function(someLib) { });
2. 代码库的使用方式
如果我们依赖一个模块库,TypeScript要求在用户代码中这样使用它,
// 直接import即可,TypeScript会根据模块名去寻找.d.ts文件import * as moment from "moment";function getThing(): moment;
3. .d.ts文件的编写方式
一个模块库可能会导出三种类型的东西:对象,类,函数。
需要注意的是,ES6 module只能导出一个对象,而CommonJS还可以导出类或者函数。
例如,
// ES6 module导出一个对象export {xxx}; // 导出方式import {xxx} from 'yyy'; // 导入方式// ES module默认导出,只是导出一个名为default的变量export default xxx; // 默认导出是以下导出方式的语法糖export {xxx as default}; // 将导出的xxx变量重命名为defaultimport xxx from 'yyy'; // 使用默认导出的变量,是以下导入方式的语法糖import {default as xxx} from 'yyy'; // 将导入的名为default的变量重命名// CommonJS导出一个对象module.exports = {xxx}; // 导出方式const {xxx} = require('yyy'); // 导入方式// CommonJS导出一个类module.exports = class {}; // 导出方式const cls = require('yyy'); // 导入方式// CommonJS导出一个函数module.exports = function(){ }; // 导出方式const fn = require('yyy'); // 导入方式
TypeScript要求针对模块库,导出不同类型的东西,需要编写不同的.d.ts文件。
(1)导出一个对象(官网例子:module.d.ts)
// 如果模块库是UMD,导出一个全局对象myLibexport as namespace myLib;// 如果模块库导出的对象有方法,例如导出一个这样的对象 {myMethod,myOtherMethod}export function myMethod(a: string): string;export function myOtherMethod(a: number): number; // 如果模块库导出了一个类型,例如 {someType}export interface someType { name: string; length: number; extras?: string[]; }// 可以声明模块导出的对象,有哪些属性export const myField: number;// 导出一个名字空间,这个名字空间中可以有类型,属性,和方法export namespace subProp { // import { subProp } from 'yourModule'; 其中subProp是一个名字空间 // subProp.foo(); 名字空间中的方法 // 或者 import * as yourMod from 'yourModule'; 其中 import * as yourMod 将整个模块看做yourMod // yourMod.subProp.foo(); export function foo(): void; }
(2)导出一个类(官网例子:module-class.d.ts)
// 如果模块库是UMD,导出一个全局对象myLibexport as namespace myClassLib;// 表明模块只导出了一个类,// 注意,ES module只能导出一个对象,不能导出一个类export = MyClass;// 声明导出的这个类的构造器,属性,和方法declare class MyClass { // 构造器 constructor(someParam?: string); // 属性 someProperty: string[]; // 方法 myMethod(opts: MyClass.MyClassMethodOptions): number; }// 如果导出的这个类,还可以做为名字空间来使用declare namespace MyClass { // 名字空间中的类型 // const MyClass = require('yyy'); // const x: MyClass.MyClassMethodOptions export interface MyClassMethodOptions { width?: number; height?: number; } }
(3)导出一个方法(官网例子:module-function.d.ts)
// 如果模块库是UMD,导出一个全局函数myFuncLibexport as namespace myFuncLib;// 表明模块只导出了一个函数,// 注意,ES module只能导出一个对象,不能导出一个函数export = MyFunction;// 导出的函数可以具有多个重载版本declare function MyFunction(name: string): MyFunction.NamedReturnType;declare function MyFunction(length: number): MyFunction.LengthReturnType; // 如果导出的这个函数,还可以做为名字空间来使用declare namespace MyFunction { // 名字空间中的类型 // const MyFunction = require('yyy'); // const x: MyFunction.LengthReturnType export interface LengthReturnType { width: number; height: number; } // 名字空间中的类型 // const MyFunction = require('yyy'); // const x: MyFunction.NamedReturnType export interface NamedReturnType { firstName: string; lastName: string; } // 名字空间中的属性 export const defaultName: string; // 名字空间中的属性 export let defaultLength: number; }
UMD
1. 代码库的表现形式
UMD可以被全局代码库所引用,也可以被模块库所引用。 (1)被全局代码库所引用 需要增加 (2)被模块库所引用 与模块库的 仍然是一个模块库或UMD。 同模块库和或UMD相同。 官网例子: 和全局代码库一样,为全局对象增加了一个属性。 同全局代码库一样。 官网例子:global-plugin.d.ts 和全局代码库一样,修改了全局变量的属性。 同全局代码库一样。 官网例子:global-modifying-module.d.ts2. 代码库的使用方式
/// <reference types="moment" />function getThing(): moment;
/// <reference types="..." />
指令,以找到相关的.d.ts
文件。import * as someLib from 'someLib';
3. .d.ts文件的编写方式
.d.ts
文件编写方式相同。模块库或UMD的插件(Module Plugin or UMD Plugin)
1. 代码库的表现形式
2. 代码库的使用方式
3. .d.ts文件的编写方式
全局代码库的插件(Global Plugin)
1. 代码库的表现形式
2. 代码库的使用方式
3. .d.ts文件的编写方式
// 对被增加属性的全局变量进行声明,其中包括添加的属性interface Number {
toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string;
toBinaryString(callback: MyLibrary.BinaryFormatCallback, opts?: MyLibrary.BinaryFormatOptions): string;
}// 全局添加了一个名字空间,其中包含类型,以及类型别名declare namespace MyLibrary { // 类型别名
// const x: window.MyLibrary.BinaryFormatCallback
type BinaryFormatCallback = (n: number) => string; // 类型
// const x: window.MyLibrary.BinaryFormatOptions
interface BinaryFormatOptions {
prefix?: string;
padding: number;
}
}
全局代码库的修改模块(Global-modifying Modules)
1. 代码库的表现形式
2. 代码库的使用方式
3. .d.ts文件的编写方式
// 声明对全局空间造成的修改declare global { // 类型
interface String {
fancyFormat(opts: StringFormatOptions): string;
}
}// 全局修改模块导出的类型export interface StringFormatOptions {
fancinessLevel: number;
}// 全局修改模块导出的函数export function doSomething(): void;// 如果全局修改模块什么也没有导出export { };
作者:何幻
链接:https://www.jianshu.com/p/9b91aa120550
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章