Identify the type of library

Currently, there are roughly three types of class libraries: global class library, module class library and UMD class library.

Global class library

A global library is one that can be accessed from the global namespace (for example, without any import). Many libraries simply expose one or more global variables.

You’ll often see how to reference libraries in HTML with script tags in the tutorial documentation for global libraries:

<script src="http://a.great.cdn.for/someLib.js"></script>
Copy the code

Most of the popular global access libraries today are actually written as UMD libraries. Before writing the global declaration file, be sure to verify that the library is really not UMD.

When you look at the source code for the global library, you usually see:

  • One of the topvarStatements orfunctionThe statement
  • One or more assignment statements towindow.someName
  • Assuming thatDOMThe original value asdocumentwindowThere is a
function createGreeting(s) {
  return "Hello, " + s;
}
Copy the code
window.someName = function () {};
Copy the code

Module library

Some libraries can only work in the context of a module loader. For example, Express only works in Node.js, so it needs to be loaded using the CommonJS require function.

You’ll usually see the following description in the documentation of a modular library:

var someLib = require("someLib");
Copy the code

or

define(... ['someLib'].function(someLib) {});
Copy the code

From the source:

  • The module library will contain at least one of the following representative entries:

    • Unconditional callrequiredefine
    • likeimport as a from 'b'; or export c;Such a statement
    • Assigned toexportsmodule.exports
  • They rarely contain:

    • rightwindowglobalThe assignment of

UMD class library

UMD modules are modules that can be used either as modules (through imports) or globally (in an environment without a module loader).

The UMD module checks for the presence of a module loader environment. This is a very descriptive description of the observed modules, which would look like this:

(function (root, factory) {
  if (typeof define === "function" && define.amd) {
      define(["libName"], factory);
  } else if (typeof module= = ="object" && module.exports) {
      module.exports = factory(require("libName"));
  } else {
      root.returnExports = factory(root.libName);
  }
}(this.function (b)
Copy the code

If you see tests like Typeof define, Typeof Window, or Typeof Module in the library’s source code, especially at the top of the file, it’s almost a UMD library.

UMD library documentation often includes examples that show how to use the

How do I introduce external class libraries?

During development, it is inevitable to reference third-party JavaScript class libraries. Library classes and methods can be called by direct reference, but not by TypeScript’s strict type checking mechanism. Take jquery as an example:

npm i jquery
Copy the code
import $ from "jquery";
//Error! Could not find a declaration file for module 'jquery'.
Copy the code

The jquery template declaration file cannot be found. When using a non-TS class library, we have to write a declaration file for it and expose its API. Some source code contains the declaration file, and some need to be installed separately.

With the efforts of the community, most of the classification library declaration files have been written.

  1. You can do your own search on this website.
  2. If you encounter one that hasn’t written a declaration yet, it’s your chance to contribute to the community.
NPM i@types /jquery --save-devCopy the code

How do I write a declaration file?

Where is the declaration file?

  • directorysrc/@types/In thesrcNew directory@typesDirectory, in which to write.d.tsDeclaration file, declaration file is automatically recognized, you can write your own declaration file here for some modules that do not have declaration file, actually intsconfig.jsontypeRootsFields contained in the scope written.d.ts, will be automatically identified;
  • And declaredjsFile in the same directory with the same name.d.tsFiles, which are also automatically identified;
  • Set up thepackage.jsonIn thetypesAttribute value, such as./index.d.ts. Then the system will recognize the declaration file of the address. Also when we put our ownjsLibrary published tonpmOn, bind the declaration file in this way.
  • ifnpmModule installation, e.g@type/reactIt is stored innode_modules/@types/Under the path.

The statement syntax

  • declare varDeclare global variables

    Statement:

    declare const foo: number;
    Copy the code

    In general, global variables are non-modifiers, so in most cases you should use const instead of var or let.

  • declare functionDeclaring global functions

    Code:

    greet("hello");
    Copy the code

    Statement:

    declare function greet(greeting: string) :void;
    Copy the code

    Support for function overloading

    declare function greet(greeting: number) :void;
    declare function greet(greeting: string) :void;
    Copy the code
  • declare namespaceDeclares an object with attributes

    Describes types or values accessed using dot notation.

    Code:

    let result = myLib.makeGreeting("hello, world");
    let count = myLib.numberOfGreetings;
    Copy the code

    Statement:

    declare namespace myLib {
      function makeGreeting(greeting: string) :void;
      let numberOfGreetings: number;
    }
    Copy the code
  • In addition to global variables, there may be some types that we want to expose as well. In a type declaration file, we can declare a global interface or type directly using interface or type.

    Code:

    greet({
      greeting: "hello world".duration: 4000});Copy the code

    Statement:

    interface GreetingSettings {
      greeting: string; duration? :number; color? :string;
    }
    declare function greet(greeting: GreetingSettings) :void;
    Copy the code
  • Tissue types

    Code:

    const g = new Greeter("Hello");
    g.log({ verbose: true });
    g.alert({ modal: false.title: "Current Greeting" });
    Copy the code

    Organize types using namespaces:

    declare namespace Greeter {
      interfaceLogOptions { verbose? :boolean;
      }
      interface AlertOptions {
        modal: boolean; title? :string; color? :string; }}Copy the code

    You can also create nested namespaces in a declaration:

    declare namespace Greeter.Options {
      // Refer to via Greeter.Options.Log
      interfaceLog { verbose? :boolean;
      }
      interface Alert {
        modal: boolean; title? :string; color? :string; }}Copy the code
  • declare classDeclaring a global class

    Code:

    const myGreeter = new Greeter("hello, world");
    myGreeter.greeting = "howdy";
    myGreeter.showGreeting();
    
    class SpecialGreeter extends Greeter {
      constructor() {
        super("Very special greetings"); }}Copy the code

    Statement:

    declare class Greeter {
      constructor(greeting: string);
      greeting: string;
      showGreeting(): void;
    }
    Copy the code

Declaration file

Global class library

- js file ' 'js function globalLib(options) {console.log(options); } globalLib. Version = "1.0.0"; globalLib.doSomething = function () { console.log("global lib do something"); }; Ts globalLib({a: 1}); // Error: Cannot find name 'globalLib'. Ts declare function globalLib(options: globallib. options): void; ts declare function globalLib(options: globalLib. declare namespace globalLib { const version: string; function doSomething(): void; interface Options { [key: string]: any; The ``` `declare 'keyword can provide declarations for external variables. The namespace is merged with the declaration of the function, adding some default properties to the function. Interface parameters are specified as indexable types that accept arbitrary attributes.Copy the code

The module class library

The following files are for 'CommonJS' modules: js const version = "1.0.0"; function doSomething() { console.log("moduleLib do something"); } function moduleLib(options) { console.log(options); } moduleLib.version = version; moduleLib.doSomething = doSomething; module.exports = moduleLib; We also use it in the ts file. ```ts import module from "./module-lib/index.js"; // Error: Could not find a declaration file for module './module-lib/index.js'. ' ' ```ts declare function moduleLib(options: Options): void; interface Options { [key: string]: any; } declare namespace moduleLib { const version: string; function doSomething(): void; } // export = moduleLib; The only difference with the global library declaration file is that the 'export' output is required.Copy the code

UMD class library

(function (root, factory) {
  if (typeof define === "function" && define.amd) {
    define(factory);
  } else if (typeof module= = ="object" && module.exports) {
    module.exports = factory();
  } else {
    root.umdLib = factory();
  }
})(this.function () {
  return {
    version: "1.0.0".doSomething() {
      console.log("umd lib do something"); }}; });Copy the code

Declaration Document:

declare namespace umdLib {
  const version: string;
  function doSomething() :void;
}

export as namespace umdLib;

export = umdLib;
Copy the code

Unlike other libraries, the export as namespace umdLib statement has been added, which is required if declared for the UMD library.

Umds can also be referenced globally.

<script src="src/libs/umd-lib.js"></script>
Copy the code
umdLib.doSomething();
// Error! 'umdLib' refers to a UMD global, but the current file is a module. Consider adding an import instead.
Copy the code

Error: umdLib is a UMD library.

This can be turned off with the configuration item “allowUmdGlobalAccess”: true.

The module

Sometimes we want to add custom methods to a third-party library.

  • Module plug-ins:declare module
    import m from "moment";
    declare module "moment" {
      export function myFunc() :void;
    }
    m.myFunc = () = > {};
    Copy the code
  • Global plugin:declare global
    declare global {
      namespace globalLib {
        export function doAnything() :void;
      }
    }
    globalLib.doAnything = () = > {
      console.log("globalLib do anything");
    };
    Copy the code

    This will cause global pollution, so it is not recommended.

Statement depends on

When a class library is large, the declaration files are also divided by module, so there is a dependency between the declaration files. Take jquery as an example:

/**** Module depends on ****/
/// <reference types="sizzle" />
/**** Path dependency ****/
/// <reference path="JQueryStatic.d.ts" />
/// <reference path="JQuery.d.ts" />
/// <reference path="misc.d.ts" />
/// <reference path="legacy.d.ts" />

export = jQuery;
Copy the code

The TypeScript project family

  • Don’t use TypeScript? Namespace.
  • TS effort: declared merger
  • How do I introduce external class libraries into TypeScript?
  • Get started, tsconfig (file options)
  • Get started, tsconfig (compilation option)
  • Would you like to learn a more efficient way to build TS (engineering introduction)
  • TS compiler! From ts – loader to Babel
  • Code check tool! From TSLint to ESLint
  • TS single test tool! Ts – jest and Babel/jest