Skip to content
Created: October 12, 2020

type declaration ​

  • The declaration file allows us to use the system without refactoring JS into TS. We only need to add the declaration file.
  • Type declarations will be deleted during compilation and will not affect the real code.
  • The keyword declare means declaration, and we can use it to make various declarations:
ts
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型

1. Ordinary type declaration ​

ts
declare let name: string; //变量
declare let age: number; //变量
declare function getName(): string; //方法
declare class Animal {
  name: string;
} //类
console.log(name, age);
getName();
new Animal();
export default {};

Declare jQuery objects

ts
declare const $: (selector: string) => {
  //变量
  click(): void;
  width(length: number): void;
};
$("#root").click();
console.log($("#root").width);

2. external enumeration ​

  • External enumerations are enumeration types defined using declare enum
  • External enumerations are used to describe the shape of existing enumeration types.
ts
declare enum Seasons {
  Spring,
  Summer,
  Autumn,
  Winter,
}

let seasons = [Seasons.Spring, Seasons.Summer, Seasons.Autumn, Seasons.Winter];
  • The types defined by declare will only be used for compile-time checking and will be deleted from the compilation results.The compilation result of the above example is as follows
ts
var seasons = [Seasons.Spring, Seasons.Summer, Seasons.Autumn, Seasons.Winter];
  • You can also use declare and const at the same time
ts
declare const enum Seasons {
  Spring,
  Summer,
  Autumn,
  Winter,
}

let seasons = [Seasons.Spring, Seasons.Summer, Seasons.Autumn, Seasons.Winter];

Compilation result

ts
var seasons = [0 /* Spring */, 1 /* Summer */, 2 /* Autumn */, 3 /* Winter */];

3. namespace ​

  • If a global variable contains many sub-properties, namespace may be used
  • The namespace in the declaration file indicates that a global variable contains many sub-properties
  • There is no need to use declare to declare properties or methods inside a namespace
ts
declare namespace $ {
  function ajax(url: string, settings: any): void;
  let name: string;
  namespace fn {
    function extend(object: any): void;
  }
}
$.ajax("/api/users", {});
$.fn.extend({
  log: function (message: any) {
    console.log(message);
  },
});
export {};

4. type declaration file ​

  • We can put the type declaration in a separate type declaration file
  • Type declarations can be used in type declaration files
  • The file naming convention is *.d.ts
  • Looking at the type declaration file can help you understand how the library is used

4.1 jquery.d.ts ​

typings\jquery.d.ts

ts
declare const $: (selector: string) => {
  click(): void;
  width(length: number): void;
};

4.2 tsconfig.json ​

tsconfig.json

ts
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2015",
    "outDir":"lib"
  },
  "include": [
    "src/**/*",
    "typings/**/*"
  ]
}

4.3 test.js ​

src\test.ts

ts
$("#button").click();
$("#button").width(100);
export {};

5. Third Party Statement Document ​

  • You can install and use third-party declaration files
  • @types is an agreed prefix. All type libraries declared by third parties will have such a prefix.
  • There are many built-in objects in JavaScript that can be treated as declared types in TypeScript
  • Built-in objects refer to objects that exist on the global scope (Global) according to standards.The standards here refer to standards for ECMAScript and other environments (such as DOM)
  • The type declaration files of these built-in objects are included in the type declaration files of the TypeScript core library.

5.1 Using jquery ​

cnpm i jquery -S
ts
//对于common.js风格的模块必须使用 import * as
import * as jQuery from "jquery";
jQuery.ajax("/user/1");

5.2 Installation declaration file ​

ts
cnpm i @types/jquery -S

5.3 Write your own declaration file ​

  • Module search rules
  • node_modules@types\jquery/index.d.ts
  • We can write the declaration file ourselves and configure tsconfig.json

5.3.1 index.d.ts ​

types\jquery\index.d.ts

ts
declare function jQuery(selector: string): HTMLElement;
declare namespace jQuery {
  function ajax(url: string): void;
}
export default jQuery;

5.3.2 tsconfig.json ​

  • If paths are configured, then when importing the package, it will automatically go to the paths directory to find the type declaration file.
  • In tsconfig.json, we configure path mapping through the paths attribute in compilerOptions
  • paths is a list of module names to baseUrl-based path mappings
ts
{
  "compilerOptions": {
    "baseUrl": "./",// 使用 paths 属性的话必须要指定 baseUrl 的值
    "paths": {
      "*":["types/*"]
    }
}
ts
import $ from "jquery";
$.ajax("get");

5.4 Possible locations of npm declaration files ​

  • node_modules/jquery/package.json
    • "types":"types/xxx.d.ts"
  • node_modules/jquery/index.d.ts
  • node_modules/@types/jquery/index.d.ts
  • typings\jquery\index.d.ts

5.5 Find declaration files ​

  • If it is a manually written declaration file, it needs to meet one of the following conditions to be correctly recognized.
  • Specify a type declaration file address for the types or typings field in package.json
  • In the project root directory, write an index.d.ts file
  • For the entry file (the entry file specified by the main field in package.json), write a .d.ts file with the same name and different suffixes
ts
{
    "name": "myLib",
    "version": "1.0.0",
    "main": "lib/index.js",
    "types": "myLib.d.ts",
}
  • Find myLib.d.ts first
  • If not, look for index.d.ts again.
  • Haven’t found lib/index.d.js yet
  • If you still can’t find it, it’s assumed that there is no type declaration.

6. Extend the type of global variables ​

6.1 Extended local variable types ​

ts
declare var String: StringConstructor;
interface StringConstructor {
  new (value?: any): String;
  (value?: any): string;
  readonly prototype: String;
}
interface String {
  toString(): string;
}
ts
//扩展类的原型
interface String {
  double(): string;
}

String.prototype.double = function () {
  return this + "+" + this;
};
console.log("hello".double());

//扩展类的实例
interface Window {
  myname: string;
}
console.log(window.myname);
//export {} 没有导出就是全局扩展

6.2 Global expansion within the module ​

types\global\index.d.ts

ts
declare global {
  interface String {
    double(): string;
  }
  interface Window {
    myname: string;
  }
}

export {};

7. Merger Statement ​

  • Two separate declarations with the same name are merged into a single declaration
  • The merged declaration has the properties of the original two declarations
KeywordUsed as typeUsed as value
classyesyes
enumyesyes
interfaceyesno
typeyesno
functionnoyes
var,let,constnoyes
  • Classes can be used as types or values, interfaces can only be used as types
ts
class Person {
  name: string = "";
}
let p1: Person; //作为类型使用
let p2 = new Person(); //作为值使用

interface Animal {
  name: string;
}
let a1: Animal;
let a2 = Animal; //接口类型不能用作值

7.1 Merging type declarations ​

  • Features that can be merged through interfaces are given to a third party for extended type declarations

use.js

ts
interface Animal {
  name: string;
}
let a1: Animal = { name: "hello ", age: 10 };
console.log(a1.name);
console.log(a1.age);
//注意不要加export {} ,这是全局的

types\animal\index.d.ts

ts
interface Animal {
  age: number;
}

7.2 Extending classes using namespaces ​

  • We can use namespace to extend classes to represent inner classes
ts
class Form {
  username: Form.Item = "";
  password: Form.Item = "";
}
//Item为Form的内部类
namespace Form {
  export class Item {}
}
let item: Form.Item = new Form.Item();
console.log(item);

7.3 Using namespace extension functions ​

We can also use namespace to extend functions

ts
function greeting(name: string): string {
  return greeting.words + name;
}

namespace greeting {
  export let words = "Hello,";
}

console.log(greeting("hello "));

7.4 Extending enumerated types using namespaces ​

ts
enum Color {
  red = 1,
  yellow = 2,
  blue = 3,
}

namespace Color {
  export const green = 4;
  export const purple = 5;
}
console.log(Color.green);

7.5 Extend Store ​

ts
import { createStore, Store } from "redux";
type StoreExt = Store & {
  ext: string;
};
let store: StoreExt = createStore((state) => state);
store.ext = "hello";

8. Generate declaration file ​

After compiling TS into JS, the type declaration is lost. We can automatically generate a JS file during compilation.

ts
{
  "compilerOptions": {
     "declaration": true, /* Generates corresponding '.d.ts' file.*/
  }
}