TypeScript支持两种方式来控制我们的作用域:
模块化:每个文件可以是一个独立的模块,支持ES Module(常用),也支持CommonJS;
命名空间:通过namespace来声明一个命名空间
模块化的使用是和JavaScript一样的
例如我们在其他文件中定义两个工具函数, 可以引入到当前文件中使用
// 其他文件中定义的工具函数
export function sum(num1: number, num2: number) {
return num1 + num2
}
export function mul(num1: number, num2: number) {
return num1 * num2
}
// 当前文件夹下引入使用
import {sum, mul} from "./utils/math"
console.log(sum(10, 20))
console.log(mul(10, 20))
命名空间在TypeScript早期时,称之为内部模块,主要目的是将一个模块内部再进行作用域的划分,防止一些命名冲突的问题。
例如我们有两个函数都命名为format, 一个是用来格式化时间, 一个是用来格式化价格的, 正常情况下, 由于名称相同一定会产生命名冲突问题
// 由于两个函数名相同, 会产生命名冲突
function format(time: string) {
return "2022-08-15"
}
function format(price: string) {
return "¥99"
}
这时候我们可以使用命名空间, 对模块内部在进行作用域划分, 防止命名冲突的问题
namespace time {
// 外部想要访问命名空间的方法, 命名空间中需要导出
export function format() {
return "2022-08-15"
}
}
namespace price {
export function format() {
return "¥99"
}
}
// 使用命名空间方法
time.format()
price.format()
外部文件想要使用我们的命名空间的话, 我们也需要将命名空间导出, 再在要使用的文件中导入即可
// 导出命名空间
export namespace time {
export function format() {
return "2022-08-15"
}
}
之前我们所有的typescript中的类型,几乎都是我们自己编写的,但是我们也有用到一些其他的类型:
const imageEl = document.getElementById("image") as HTMLImageElement
大家是否会奇怪,我们的HTMLImageElement类型来自哪里呢?甚至是document为什么有getElementById的方法呢?
其实这里就涉及到typescript对类型的管理和查找规则了。
我们这里先给大家介绍另外的一种typescript文件: .d.ts文件
我们之前编写的typescript文件都是 .ts 文件,这些文件最终会输出 .js 文件,也是我们通常编写代码的地方;
还有另外一种文件
.d.ts 文件
,它是用来做类型的声明(declare)。 它仅仅用来做类型检测,告知typescript我们有哪 些类型;
那么typescript会在哪里查找我们的类型声明呢?或者说这个.d.ts文件
来自哪里
内置类型声明;
外部定义类型声明;
自己定义类型声明;
内置类型声明是typescript自带的、帮助我们内置了JavaScript运行时的一些标准化API的声明文件;
比如包括Math、 Date等内置类型,也包括DOM API,比如Window、 Document等;
内置类型声明通常在我们安装typescript的环境中会带有的;
GitHub源码链接: https://github.com/microsoft/TypeScript/tree/main/lib
外部类型声明通常是我们使用一些库(比如第三方库)时,需要的一些类型声明。
这些库通常有两种类型声明方式:
方式一:在自己库中进行类型声明(编写.d.ts文件),比如axios
方式二:通过社区的一个公有库DefinitelyTyped存放类型声明文件
- 该库的GitHub地址: https://github.com/DefinitelyTyped/DefinitelyTyped/
- 我们可以使用网站查询是否有你需要使用库的声明文件: https://www.typescriptlang.org/dt/search?search=
- 比如我们安装react的类型声明: npm i @types/react --save-dev
什么情况下需要自己来定义声明文件呢?
情况一:我们使用的第三方库是一个纯的JavaScript库,没有对应的声明文件;比如lodash
情况二:我们给自己的代码中声明一些类型,方便在其他地方直接进行使用;
例如我们创建一个my.d.ts文件, 可以在该文件中声明自定义的类型
声明变量-函数-类
例如index.html文件中有下面这些代码
<script>
let myName = "chenyq";
let maAge = 18;
function myFoo() {
console.log("foo");
}
function myBar() {
console.log("bar");
}
function Person(name, age) {
this.name = name
this.age = age
}
script>
我是没办法直接在main.js中使用的, 我们可以在自己的my.d.ts文件中进行声明
// 声明变量/函数/类
declare let myName: string
declare let myAge: number
declare function myFoo(): void
declare function myFar(): void
declare class Person {
name: string
age: number
constructor(name: string, age: number)
}
声明模块
declare module 'lodash' {
export function join(arr: any[]): void
}
声明文件
在某些情况下,我们也可以声明文件:
比如在开发vue的过程中,默认是不识别我们的.vue文件的,那么我们就需要对其进行文件的声明;
比如开发中我们使用了 jpg 这类图片文件,默认typescript也是不支持的,也需要对其进行声明;
// 声明文件
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.png'
declare module '*.svg'
declare module '*.gif'
声明命名空间
我们可以进行命名空间的声明
// 声明命名空间
declare namespace $ {
export function ajax(settings: any): any
}