模块(外部模块)
-
全局模块
:在默认情况下,当开始一个新的 ts 文件中写下代码时,它处于全局命名空间中,使用全局变量空间是危险的,会有命名冲突;// foo.ts const foo = 123; // bar.ts const bar = foo;
-
文件模块
:- 文件模块也被称为外部模块,如果在 ts 文件的根级别位置含有 import 或者 export ,那么它会在这个文件中创建一个本地的作用域;
- 模块是 TS 中外部模块的简称,侧重于代码和复用;
- 模块在其自身的作用域里执行,而不是在全局作用域里;
- 一个模块里的变量、函数、类等在外部是不可见的,除非你把它导出;
- 如果想要使用一个模块里导出的变量,则需要导入;
-
模块规范
:推荐使用 CommonJS、ES 模块;
编译结果中的模块化对比
编译结果中的模块化是可配置的
-
ts 里面的代码使用的 es6 的导入和导出,编译的模块化是 es6 对比如下(没有区别):
- 导出
- 导入
- 导出
-
ts 里面的代码使用的 es6 的导入和导出,编译的模块化是 commonjs 对比如下:
- 导出
- 导入
- 导出
解决默认导入的错误
-
默认导入报错
import fs from "fs"; // 当导入 nodejs 的模块时,由于模块不是基于 ts 开发的,导出使用的是 module.export = {} ,所以会报错模块没有默认导出 fs.readFileSync("./");
-
配置文件 方式解决: 配置 “esModuleInterop”: true,启用 es 的模块化标准交互非 es 模块导出;
{ "compilerOptions": { //编译选项 "target": "es2016", // 配置编译目标代码的版本标准 "module": "commonjs", // 配置编译目标使用的模块化标准 "lib": ["es2016"], "outDir": "./dist", "strictNullChecks": true, "removeComments": true, "noImplicitUseStrict": true, "esModuleInterop": true, // 启用 es 模块化交互非 es 模块导出 "noEmitOnError": true, "moduleResolution": "node" }, "include": ["./src"] }
-
按需导入 方式解决
import { readFileSync } from 'fs'; readFileSync('./');
-
重命名的导入 方式解决
import * as fs from 'fs'; fs.readFileSync('./');
在 TS 中使用 commonjs 模块化
-
方法一:使用这种方式获取不到类型检查
-
方法二:这里可以获取到类型检查
-
方法三:方法二中使用 require,也可以获取到类型检查
TS 的模块解析
-
模块解析:应该从什么位置寻找模块;
-
TS 中,有两种模块解析策略:
classic:经典,已经成为过去- node:node 解析策略 (唯一的变化,是将 js 替换为 ts)
- 相对路径
require("./xxx")
- 非相对模块
require("xxx")
- 相对路径
-
在 tsconfig.json 中配置 “moduleResolution”: “node” 来配置模块化标准的解析方式为 node;
涉及 config.json 相关配置
{
"compilerOptions": {
//编译选项
"target": "es2016", //配置编译目标代码的版本标准
"module": "commonjs", //配置编译目标使用的模块化标准
"lib": ["es2016"],
"outDir": "./dist",
"strictNullChecks": true,
"removeComments": true, // 编译结果移除注释
"noImplicitUseStrict": true, // 编译结果中不包含 "use strict"
"esModuleInterop": true, // 启用es模块化交互非 es 模块导出
"noEmitOnError": true, // 错误时不生成编译结果
"moduleResolution": "node", // 设置解析模块的模式
},
"include": ["./src"]
}
案例:模块化优化扑克牌程序
// enums.ts
export enum Color {
heart = "♥",
spade = "♠",
club = "♣",
diamond = "♦"
}
export enum Mark {
A = "A",
two = "2",
three = "3",
four = "4",
five = "5",
six = "6",
seven = "7",
eight = "8",
nine = "9",
ten = "10",
eleven = "J",
twelve = "Q",
king = "K"
}
// types.ts
import { Color, Mark } from "./enums";
export type NormalCard = {
color: Color
mark: Mark
};
export type Deck = NormalCard[];
// funcs.ts
import { Deck } from "./types";
import { Mark, Color } from "./enums";
export function createDeck(): Deck {
const deck: Deck = [];
const marks = Object.values(Mark)
const colors = Object.values(Color)
for (const m of marks) {
for (const c of colors) {
deck.push({ color: c, mark: m })
}
}
return deck;
}
export function printDeck(deck: Deck) {
let result = "\n";
deck.forEach((card, i) => {
let str = card.color + card.mark;
result += str + "\t";
if ((i + 1) % 4 === 0) {
result += "\n";
}
})
console.log(result);
}
// index.ts
import { createDeck, printDeck } from "./funcs";
const deck = createDeck();
printDeck(deck);
TypeScript👉 带参数的模板字面量类型
上一篇