前言
小伙伴们大家好。今天将继续给大家分享TypeScript的相关知识。在进入今天的主题之前我们先来看一下这样一种场景:在我们开发一个大型项目的时候,避免不了会引入各种JavaScript文件,而在es6(不含)之前都是通过script标签将各种我们需要用到的js文件引入到页面中,那么由此就容易导致一些问题,比如在开发中一般都是多人协作开发,也就是说一个页面可能会由多个不同的人来开发,不同的人会使用不同的js文件,这个时候就有可能会产生一些同名的变量或者方法等,比如:A在a.js中定义了一个getValue的函数,而B在没见过a.js的情况下在b.js文件中同样也定义了一个名为getValue的函数,这个时候如果页面中同时引入了a.js和b.js文件,那么后引入的文件中的getValue方法就会把先引入的覆盖掉了。这显然是不合理的,于是在es6中就引入了模块的概念,而模块就能很好的解决上述问题。
模块
从ES6开始,JavaScript中引入了模块的概念,而作为超集的TypeScript也沿用了这一概念。在TypeScript1.5版本以前分为“内部模块”和“外部模块”。而自从1.5以后已经发生了变化,“内部模块”改名为“命名空间”,“外部模块”则是我们常说的“模块”。
模块只在自身的作用域里执行,而不是在全局作用域;这也就是说:定义在一个模块里的变量,函数或类等等在模块的外部是不可见的。除非我们明确的使用了 “export” 关键字导出它们,相应的,如果想在其它模块使用这些被导出的变量、函数或类等需要使用 “import” 关键字来导入它们。TypeScript中的模块跟JavaScript中的一样,也是自声明的,任何包含顶级 import 或者 export的文件都会被当成一个模块。相反,如果一个文件中不带有顶级的 import或者 export 声明,那么它的内容就是全局可见的(包括模块)。
模块的导出
前面已经提到,模块的导出是通过关键字export来实现的。模块的导出分为如下几个类型:
- 导出声明:所有的声明(如:变量,函数,类型,类型别名,接口等等)都可以通过在前面添加关键字export来导出,export必须紧跟着声明
- 导出语句:导出语句可以让export不用紧跟着声明,通过花括号{}的形式单独将变量名,类名或接口名等导出,也可以对其进行重命名导出。而上面的导出声明,export必须要放在声明的最前面才可以,这样有时候就显得不是很方便,而且有时候我们可能还需要对导出的部分进行重命名,这个时候用导出语句就方便多了
- 重新导出:重新导出就是在一个模块中通过 “export * from 模块名” 或者 **“export {xxx} from 模块名”**的形式直接将其它模块中的部分或全部内容直接导出。比如有时候我们会经常去扩展一些其它模块,并且只想导出那个模块中的部分内容,这个时候就可以用重新导出来实现了。需要注意的是 重新导出并不会在当前模块中导入那个模块或定义一个新的局部变量,而是将那个模块直接导出,类似一个通道一样
- 默认导出:还有一种导出叫做默认导出。默认导出是在export后面再加一个default关键字来实现的
- 一个模块中有且只能有一个默认导出
- 默认导出适用于导出声明同样也适用于导出语句并且导出语句不用加花括号{}
赘述了这么多,下面我们来看一下各种导出方式的具体代码实现:
- 导出声明
// 导出声明
export let name:string;//导出变量
export function getValue():void{};//导出函数
export class Person{} //导出类
export interface IPerson{}//导出接口
- 导出语句
// 导出语句
class Person{
name:string
age:number
}
function getValue():void{}
export { Person }//必须通过花括号的形式导出
export { getValue as getMyValue} //可以导出为别名
- 重新导出
// a.ts
export class Person{}
export function getValue():void{}
export let name:string
// b.ts
export * from './a.ts' //在b模块中将a模块的内容直接全部导出
// 或者
export { Person } from './a.ts' //在b模块中将a模块中的Person直接导出
- 默认导出
//一个模块中最多只能有一个默认导出
export class Person{}
export interface IPerson{}
export default function getValue():void{}
-
// 或者
export class Person{}
export interface IPerson{}
function getValue():void{}
export default getValue;
模块导入
有了模块的导出那么相应的肯定就有模块的导入。模块的导出是将模块中的变量,函数,类等内容导出去供别的模块使用,那么其它模块想使用这些内容就得需要通过模块导入把它们导进来后再使用。
模块的导入也很简单,只需要通过关键字 “import” 就可以将模块或者内容导入了。模块的导入也有以下几种方式:
- 按导出内容导入:按导出内容导入需要借花括号{}来实现。例如:import { 内容 } from ‘模块名’,花括号中的内容名称必须与模块导出的名称一致,就是说导出时是什么名称导入时也得用这个名称,多个内容可用逗号分隔一起导入
- 重命名导入:我们也可以将其它模块导出的内容进行重命名,依然需要借助花括号实现。如:import { 内容 as 别名} from '模块名’
- 变量导入:所谓的变量导入其实就是将整个模块导入到一个变量中,然后再通过变量来访问模块中的具体内容,如:import * as 变量 from ‘模块名’、
- 副作用导入:所谓的副作用导入其实是一种不推荐的导入法,比如有些时候一些模块会设置一些全局状态供其它模块使用,这些模块没有任何的export导出,但又需要让其它模块使用,这个时候就可以是使用副作用导入。如: import '模块名’
- 默认导入:默认导入就是导入其它模块中的默认导出的内容,默认导入不需要使用花括号{}可以直接通过关键字import进行导入,并且导入时的名称也可以不用跟导出的名称一致
- 按导出内容导入
// a.ts
export function sayHello():void{}
export class Person{}
// b.ts
import { sayHello, Person } from './a.ts'
- 重命名导入
// a.ts
export function sayHello():void{}
export class Person{}
// b.ts
import { sayHello as sayHi, Person as Per } from './a.ts'
- 变量导入
// a.ts
export function sayHello():void{}
export class Person{}
// b.ts
import * as person from './a.ts'
//使用时用变量.xxx使用
person.sayHello()
let p = new person.Person()
- 副作用导入
// a.ts
function sayHello():void{}
class Person{}
interface IPerson{}
type AllPerson = Person | IPerson
// b.ts
import './a.ts'
//使用
sayHello();
class Employee extends Person implements IPerson
- 默认导入
// a.ts
export default class Person{}
//b.ts
// 默认导入变量名可以任意命名
import Person from './b.ts'
// 或者
import Employee from './b.ts'
// 无论是Person 还是Employee 都代表的是a模块中导出的Person类
export = 和 import = require()
在CommonJS和AMD模块中都有一个叫exports的变量,这个变量可被赋值为一个对象。这种情况就类似与我们上面所学的默认导出(export default)语法。虽然类似,但是TypeScript并不能exports兼容CommonJS和AMD的exports语法。为了能够支持CommonJS和AMD语法,TypeScript为我们提供了一种新的导出导入语法,即:export = xxx,import xxx = require(模块名)
如果使用但是 export = 的形式导出的模块,则必须要使用 import xxx = require(模块名) 的形式导入
// a.ts
class Perosn{
}
export = Person
// b.ts
import Per = require('./a.ts')
let p = new Per();
总结
本次我们分享了TypeScript中的模块导入和导出的几种方式和一些技巧,最后还分享了TypeScript中的模块导入导出如何能够兼容CommonJS和AMD的语法。从而让大家对TypeScript中的模块导入导出有了更进一步的了解。
本次分享就到这里了,喜欢的小伙伴欢迎点赞评论加关注哦!