Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • 数据类型

    • 初识typescript及数据类型
    • 类
    • 接口
    • 泛型
    • 结构类型系统
    • 类型保护
    • 类型变换
    • 模块和命名空间
    • 类型声明
      • 类型声明
        • 1. 普通类型声明
        • 2. 外部枚举
        • 3. namespace
        • 4. 类型声明文件
        • 4.1 jquery.d.ts
        • 4.2 tsconfig.json
        • 4.3 test.js
        • 5. 第三方声明文件
        • 5.1 使用jquery
        • 5.2 安装声明文件
        • 5.3 自己编写声明文件
        • 5.3.1 index.d.ts
        • 5.3.2 tsconfig.json
        • 5.4 npm声明文件可能的位置
        • 5.5 查找声明文件
        • 6. 扩展全局变量的类型
        • 6.1 扩展局部变量类型
        • 6.2 模块内全局扩展
        • 7. 合并声明
        • 7.1 合并类型声明
        • 7.2 使用命名空间扩展类
        • 7.3 使用命名空间扩展函数
        • 7.4 使用命名空间扩展枚举类型
        • 7.5 扩展Store
        • 8. 生成声明文件
    • null和undefined
  • 实践应用

  • 《TypeScript》学习笔记
  • 数据类型
mamingjuan
2020-10-12
目录

类型声明

# 类型声明

  • 声明文件可以让我们不需要将JS重构为TS,只需要加上声明文件就可以使用系统
  • 类型声明在编译的时候都会被删除,不会影响真正的代码
  • 关键字 declare 表示声明的意思,我们可以用它来做出各种声明:
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
1
2
3
4
5
6

# 1. 普通类型声明

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 {};
1
2
3
4
5
6
7
8

声明jQuery对象

declare const $: (selector: string) => { //变量
    click(): void;
    width(length: number): void;
};
$('#root').click();
console.log($('#root').width);
1
2
3
4
5
6

# 2. 外部枚举

  • 外部枚举是使用declare enum定义的枚举类型
  • 外部枚举用来描述已经存在的枚举类型的形状
declare enum Seasons {
    Spring,
    Summer,
    Autumn,
    Winter
}

let seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
1
2
3
4
5
6
7
8
9
10
11
12
13
  • declare 定义的类型只会用于编译时的检查,编译结果中会被删除。上例的编译结果如下
var seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
1
2
3
4
5
6
  • 也可以同时使用declare 和 const
declare const enum Seasons {
    Spring,
    Summer,
    Autumn,
    Winter
}

let seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
1
2
3
4
5
6
7
8
9
10
11
12
13

编译结果

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

# 3. namespace

  • 如果一个全局变量包括了很多子属性,可能使用namespace
  • 在声明文件中的namespace表示一个全局变量包含很多子属性
  • 在命名空间内部不需要使用 declare 声明属性或方法
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 {};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 4. 类型声明文件

  • 我们可以把类型声明放在一个单独的类型声明文件中
  • 可以在类型声明文件中使用类型声明
  • 文件命名规范为*.d.ts
  • 观看类型声明文件有助于了解库的使用方式

# 4.1 jquery.d.ts

typings\jquery.d.ts

declare const $:(selector:string)=>{
    click():void;
    width(length:number):void;
}
1
2
3
4

# 4.2 tsconfig.json

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2015",  
    "outDir":"lib"
  },
  "include": [
    "src/**/*",
    "typings/**/*"
  ]
}
1
2
3
4
5
6
7
8
9
10
11

# 4.3 test.js

src\test.ts

$('#button').click();
$('#button').width(100);
export {};
1
2
3

# 5. 第三方声明文件

  • 可以安装使用第三方的声明文件
  • @types是一个约定的前缀,所有的第三方声明的类型库都会带有这样的前缀
  • JavaScript 中有很多内置对象,它们可以在 TypeScript 中被当做声明好了的类型
  • 内置对象是指根据标准在全局作用域(Global)上存在的对象。这里的标准是指 ECMAScript 和其他环境(比如 DOM)的标准
  • 这些内置对象的类型声明文件,就包含在TypeScript 核心库的类型声明文件中

# 5.1 使用jquery

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

# 5.2 安装声明文件

cnpm i @types/jquery -S
1

# 5.3 自己编写声明文件

  • 模块查找规则 (opens new window)
  • node_modules@types\jquery/index.d.ts
  • 我们可以自己编写声明文件并配置tsconfig.json
# 5.3.1 index.d.ts

types\jquery\index.d.ts

declare function jQuery(selector:string):HTMLElement;
declare namespace jQuery{
  function ajax(url:string):void
}
export default jQuery;
1
2
3
4
5
# 5.3.2 tsconfig.json
  • 如果配置了paths,那么在引入包的的时候会自动去paths目录里找类型声明文件
  • 在 tsconfig.json 中,我们通过 compilerOptions 里的 paths 属性来配置路径映射
  • paths是模块名到基于baseUrl的路径映射的列表
{
  "compilerOptions": {
    "baseUrl": "./",// 使用 paths 属性的话必须要指定 baseUrl 的值
    "paths": {
      "*":["types/*"]
    }
}
1
2
3
4
5
6
7
import $ from "jquery";
$.ajax('get');
1
2

# 5.4 npm声明文件可能的位置

  • 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 查找声明文件

  • 如果是手动写的声明文件,那么需要满足以下条件之一,才能被正确的识别
  • 给 package.json 中的 types 或 typings 字段指定一个类型声明文件地址
  • 在项目根目录下,编写一个 index.d.ts 文件
  • 针对入口文件(package.json 中的 main 字段指定的入口文件),编写一个同名不同后缀的 .d.ts 文件
{
    "name": "myLib",
    "version": "1.0.0",
    "main": "lib/index.js",
    "types": "myLib.d.ts",
}
1
2
3
4
5
6
  • 先找myLib.d.ts
  • 没有就再找index.d.ts
  • 还没有再找lib/index.d.js
  • 还找不到就认为没有类型声明了

# 6. 扩展全局变量的类型

# 6.1 扩展局部变量类型

declare var String: StringConstructor;
interface StringConstructor {
    new(value?: any): String;
    (value?: any): string;
    readonly prototype: String;
}
interface String {
    toString(): string;
}
1
2
3
4
5
6
7
8
9
//扩展类的原型
interface String {
    double():string;
}

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

//扩展类的实例
interface Window{
    myname:string
}
console.log(window.myname);
//export {} 没有导出就是全局扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 6.2 模块内全局扩展

types\global\index.d.ts

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

export  {}
1
2
3
4
5
6
7
8
9
10

# 7. 合并声明

  • 同一名称的两个独立声明会被合并成一个单一声明
  • 合并后的声明拥有原先两个声明的特性
关键字 作为类型使用 作为值使用
class yes yes
enum yes yes
interface yes no
type yes no
function no yes
var,let,const no yes
  • 类既可以作为类型使用,也可以作为值使用,接口只能作为类型使用
class Person{
    name:string=''
}
let p1:Person;//作为类型使用
let p2 = new Person();//作为值使用

interface Animal{
    name:string
}
let a1:Animal;
let a2 = Animal;//接口类型不能用作值
1
2
3
4
5
6
7
8
9
10
11

# 7.1 合并类型声明

  • 可以通过接口合并的特性给一个第三方为扩展类型声明

use.js

interface Animal{
    name:string
}
let a1:Animal={name:'hello ',age:10};
console.log(a1.name);
console.log(a1.age);
//注意不要加export {} ,这是全局的
1
2
3
4
5
6
7

types\animal\index.d.ts

interface Animal{
    age:number
}
1
2
3

# 7.2 使用命名空间扩展类

  • 我们可以使用 namespace 来扩展类,用于表示内部类
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);
1
2
3
4
5
6
7
8
9
10

# 7.3 使用命名空间扩展函数

我们也可以使用 namespace 来扩展函数

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

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

console.log(greeting('hello '))
1
2
3
4
5
6
7
8
9

# 7.4 使用命名空间扩展枚举类型

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

namespace Color {
    export const green=4;
    export const purple=5;
}
console.log(Color.green)
1
2
3
4
5
6
7
8
9
10
11

# 7.5 扩展Store

import { createStore, Store } from 'redux';
type StoreExt = Store & {
    ext: string
}
let store: StoreExt = createStore(state => state);
store.ext = 'hello';
1
2
3
4
5
6

# 8. 生成声明文件

把TS编译成JS后丢失类型声明,我们可以在编译的时候自动生成一份JS文件

{
  "compilerOptions": {
     "declaration": true, /* Generates corresponding '.d.ts' file.*/
  }
}
1
2
3
4
5
上次更新: 2026/01/07, 09:20:46
模块和命名空间
null和undefined

← 模块和命名空间 null和undefined→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式