【TypeScript】深入学习TypeScript模块化

TypeScript学习:TypeScript从入门到精通

蓝桥杯真题解析:蓝桥杯Web国赛真题解析

个人简介:即将大三的学生,热爱前端,热爱生活
你的一键三连是我更新的最大动力❤️!


前言

最近博主一直在创作TypeScript的内容,所有的TypeScript文章都在我的TypeScript从入门到精通专栏里,每一篇文章都是精心打磨的优质好文,并且非常的全面和细致,期待你的订阅❤️

本篇文章将深入去讲解TypeScript中的模块化,这也许会是你看过的最全面最细致的TypeScript教程,点赞关注收藏不迷路!

文章目录

  • 前言
  • 1、模块定义
  • 2、ES模块语法
    • TS特定的语法
  • 3、CommonJS语法
  • 4、TypeScript模块选项
    • 模块解析选项
    • 模块输出选项
  • 5、TypeScript命名空间
  • 结语

1、模块定义

TypeScript中,就像在EC5中一样,任何包含顶级importexport 的文件都被认为是一个模块

相反的,一个没有任何顶级导入或导出声明的文件被视为一个脚本,其内容可在全局范围内使用(因此也可用于模块)

模块在自己的范围内执行,而不是在全局范围内。这意味着在模块中声明的变量、函数、类等在模块外是不可见的,除非它们被明确地用某种导出形式导出。相反,要使用从不同模块导出的变量、函数、类、接口等,必须使用导入的形式将其导入。

JavaScript规范声明,任何没有export 或顶层 awaitJavaScript文件都应该被认为是一个脚本而不是一个模块

如果你有一个目前没有任何导入或导出的文件,但你希望它被当作一个模块来处理,可以添加这一行:

export {};

这将改变该文件,使其成为一个什么都不输出的模块。无论你的模块目标是什么,这个语法都有效

TypeScript中能够使用JavaScript的模块化语法,并在此基础上提供了一些额外的语法

2、ES模块语法

一个文件可以通过export default 声明一个主要出口:

// @filename: hello.ts
export default function helloWorld() {
    console.log("Hello, world!");
}

一个文件中export default只能有一个

通过import导入:

// @filename: a.ts(与 hello.ts同级)
import hello from "./hello";
hello();

import引入export default导出的内容时可以自定义导入名称,如上面导出的函数名为helloWorld,但引入时我们自定义了hello的名称

除了默认的导出,还可以通过省略defaultexport ,导出多个变量和函数的:

// @filename: hello.ts
export var a = 3.14;
export let b = 1.41;
export const c = 1.61;
export class D {}
export function fn(num: number) {
    console.log(num);
}

可以只使用一个export导出:

var a = 3.14;
let b = 1.41;
const c = 1.61;
class D {}
function fn(num: number) {
    console.log(num);
}
export { a, b, c, D, fn };

通过import{}实现按需导入:

// @filename: a.ts(与 hello.ts同级)
import { a, b, c, D, fn } from "./hello";
console.log(a, b, c, new D());
fn(1);

可以使用 import {old as new} 这样的格式来重命名一个导入:

// @filename: a.ts(与 hello.ts同级)
// 仅引入a,c,fn 并重命名a和fn
import { a as A, c, fn as FN } from "./hello";
console.log(A, c);
FN(1);

可以把所有导出的对象,用* as name ,把它们放到同一个命名空间name

// @filename: a.ts(与 hello.ts同级)
// export导出的所有内容放到了命名空间 F 中
import * as F from "./hello";
console.log(F.a, F.c);
F.fn(1);

export defaultexport一起使用:

// @filename: hello.ts
export var a = 3.14;
export let b = 1.41;
export const c = 1.61;
export class D {}
export function fn(num: number) {
    console.log(num);
}
export default function helloWorld() {
    console.log("Hello, world!");
}
// @filename: a.ts(与 hello.ts同级)
import hello, { a, b, c, D, fn } from "./hello";
console.log(a, b, c, new D());
fn(1);
hello();

直接导入一个文件

通过import "file Path" 导入一个文件,而不把任何变量纳入你的当前模块:

// @filename: a.ts(与 hello.ts同级)
import "./hello";

在这种情况下, import 没有任何作用,但 hello.ts 中的所有代码都将被解析,这可能引发影响其他对象的副作用

TS特定的语法

类型可以使用与JavaScript值相同的语法进行导出和导入:

// @filename: hello.ts
export type Cat = {};
export interface Dog {}
// @filename: a.ts(与 hello.ts同级)
import { Cat, Dog } from "./hello";
let a: Cat, b: Dog;

TypeScript用两个概念扩展了 import 语法,用于声明一个类型的导入:

import type

这是一个导入语句,导入的变量只能用作类型:

// @filename: hello.ts
export const createCatName = () => "fluffy";

在这里插入图片描述

内联类型导入

TypeScript 4.5还允许以type为前缀的单个导入,以表明导入的引用是一个类型:

// @filename: hello.ts
export type Cat = {};
export interface Dog {}
export const createCatName = () => "fluffy";
// @filename: a.ts(与 hello.ts同级)
// 表明Cat和Dog为类型
import { createCatName, type Cat, type Dog } from "./hello";
type Animals = Cat | Dog;
const name = createCatName();

3、CommonJS语法

若使用CommonJS语法报错,则需要先在项目根目录运行:npm i --save-dev @types/node安装声明文件

通过在一个全局调用的 module 上设置 exports 属性来导出

// @filename: hello.ts
function absolute(num: number) {
    return num;
}
const a = 3;
let b = 4;
var c = 5;

module.exports = {
    a,
    b,
    newC: c, // 将c以newC的名称导出
    d: 12, // 直接导出一个值
    fn: absolute, // 将absolute以fn的名称导出
};

通过require 语句导入:

// @filename: a.ts(与 hello.ts同级)
const m = require("./hello");
console.log(m.a, m.b, m.newC, m.fn(1));

使用JavaScript中的解构功能来简化一下:

// @filename: a.ts(与 hello.ts同级)
const { d, fn } = require("./hello");
console.log(d, fn(1));

4、TypeScript模块选项

模块解析选项

模块解析是指从importrequire 语句中获取一个字符串,并确定该字符串所指的文件的过程

TypeScript包括两种解析策略:

  • 经典
  • Node

当编译器选项(tsconfig.json配置文件)中 module 不是commonjs 时,经典策略是默认的,是为了向后兼容。

Node策略复制了Node.jsCommonJS模式下的工作方式,对.ts.d.ts 有额外的检查

TypeScript中,有许多TSConfig标志影响模块策略:

  • moduleResolution
  • baseUrl
  • paths
  • rootDirs

关于这些策略如何工作的全部细节,你可以参考《模块解析》

模块输出选项

tsconfig.json配置文件中有两个选项影响JavaScript的输出:

  • target ,它决定了TS代码编译成JS的版本
  • module ,它决定了哪些代码用于模块之间的相互作用

所有模块之间的通信都是通过模块加载器进行的,编译器选项 module 决定了使用哪一个

在运行时,模块加载器负责在执行一个模块之前定位和执行该模块的所有依赖项

可以在TSConfig 模块参考 中看到所有可用的选项以及它们编译出的JavaScript代码是什么样子

5、TypeScript命名空间

TypeScript有自己的模块格式,称为 命名空间(namespaces) ,这比ES模块标准要早

这种语法对于创建复杂的定义文件有很多有用的功能,并且在DefinitelyTyped中仍然被积极使用。虽然没有被废弃,但命名空间中的大部分功能都存在于ES Modules中,官方建议使用它来与JavaScript的方向保持一致

更多关于命名空间的信息可见: namespaces参考页

结语

至此,TypeScript模块化的内容就全部结束了,关注博主下篇更精彩!

博主的TypeScript从入门到精通专栏正在慢慢的补充之中,赶快关注订阅,与博主一起进步吧!期待你的三连支持。

参考资料:TypeScript官网

如果本篇文章对你有所帮助,还请客官一件四连!❤️

你可能感兴趣的:(typescript,学习,javascript)