TypeScript内容补充

TypeScript内容补充

1、模块化开发

(1) 模块化

  • TypeScript支持两种方式来控制我们的作用域:

    • 模块化:每个文件可以是一个独立的模块,支持ES Module,也支持CommonJS;

    • 命名空间:通过namespace来声明一个命名空间

export function add(num1: number, num2: number) {
  return num1 + num2
}

export function sub(num1: number, num2: number) {
  return num1 - num2
}

(2) 命名空间namespace

  • 命名空间在TypeScript早期时,称之为内部模块,主要目的是将一个模块内部再进行作用域的划分,防止一些命名冲突的问题。
export namespace time {
  export function format(time: string) {
    return time
  }
}

export namespace price {
  export function format(price: number) {
    return price
  }
}

2、类型查找

  • 之前我们所有的typescript中的类型,几乎都是我们自己编写的,但是我们也有用到一些其他的类型:

  • 大家是否会奇怪,我们的HTMLImageElement类型来自哪里呢?甚至是document为什么可以有getElementById的方法呢?

    • 其实这里就涉及到typescript对类型的管理和查找规则了。
  • 我们这里先给大家介绍另外的一种typescript文件:.d.ts文件

    • 我们之前编写的typescript文件都是 .ts 文件,这些文件最终会输出 .js 文件,也是我们通常编写代码的地方;

    • 还有另外一种文件 .d.ts 文件,它是用来做类型的声明(declare)。 它仅仅用来做类型检测,告知typescript我们有哪些类型;

  • 那么typescript会在哪里查找我们的类型声明呢?

    • 内置类型声明;

    • 外部定义类型声明;

    • 自定义类型声明;

(1) 内置类型声明

  • 内置类型声明是typescript自带的、帮助我们内置了JavaScript运行时的一些标准化API的声明文件;

    • 包括比如Math、Date等内置类型,也包括DOM API,比如Window、Document等;
  • 内置类型声明通常在我们安装typescript的环境中会带有的;

    • https://github.com/microsoft/TypeScript/tree/main/lib

(2)外部定义类型声明和自定义声明

  • n外部类型声明通常是我们使用一些库(比如第三方库)时,需要的一些类型声明。

  • 这些库通常有两种类型声明方式:

    • 方式一:在自己库中进行类型声明(编写.d.ts文件),比如axios

    • 方式二:通过社区的一个公有库DefinitelyTyped存放类型声明文件

  • 什么情况下需要自己来定义声明文件呢?

    • 情况一:我们使用的第三方库是一个纯的JavaScript库,没有对应的声明文件;比如lodash
    • 情况二:我们给自己的代码中声明一些类型,方便在其他地方直接进行使用;

(3) 自定义声明方式

[1] 声明变量-函数-类

// index.d.ts
declare let ckName: string;
declare let ckAge: number;

declare function ckFoo(): void;

declare class Person {
  name: string;
  age: number;
  constructor(name: string, age: number);
}
// index.ts
let ckName = 'coderking'
let ckAge = 18

function ckFoo(){
    console.log(ckName, ckAge)
}

class Person {
  this.name = ckName;
  this.name = ckAge;
}

[2] 声明模块

  • 我们也可以声明模块,比如lodash模块默认不能使用的情况,可以自己来声明这个模块:
// index.d.ts
declare module "lodash" {
  export function join(arr: any[]): void;
}
  • 声明模块的语法: declare module '模块名' {}。
    • 在声明模块的内部,我们可以通过 export 导出对应库的类、函数等;

[3] declare文件

  • 在某些情况下,我们也可以声明文件:

    • 比如在开发vue的过程中,默认是不识别我们的.vue文件的,那么我们就需要对其进行文件的声明;

    • 比如在开发中我们使用了 jpg 这类图片文件,默认typescript也是不支持的,也需要对其进行声明;

// index.d.ts
declare module "*.vue"{
	import { DefineComponent } from 'vue'
	const component: DefineComponent
	
	export default component
}

declare module "*.png"{
    const src: string
    export default src
}

[4] declare命名空间

  • 比如我们在index.html中直接引入了jQuery:

    • CDN地址: https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js
  • 我们可以进行命名空间的声明:

// index.d.ts
declare namespace $ {
  export function ajax(settings: any): any;
}
  • 在index.ts中就可以使用了:
// index.ts
$.ajax({
	url: 'https://web.lyr3.cn'
	success: (res: any) => {
		console.log(res)
	}
});