# 一、TS 模块化

  在 typescript 中主要使用的 ✨ 模块化方法是 ES Module

export default A - import A from './A.js'

# 1、TS 模块

  在 typescript 中,任何没有 export 或 顶级的 JavaScript 文件 await 都应被视为脚本而不是模块。也就是官网中的Non-modules (opens new window)

  但如果我们没有任何 import 或者 export 时,我们仍然希望它作为模块处理,我们可以添加:

export {}

  关于 typescript 模块导入,也有一些注意事项:

在 Typescript 4.5 开始,我们可以使用 type 前缀,来表明被导入的是一个类型

类型导入
  • utils / math.ts
export interface IPerson {
  name: string
  age: number
}

export type IDType = number | string
  • index.ts
import type { IPerson, IDType } from './utils/type'
// import { type IPerson, type IDType } from './utils/type'

# 2、命名空间

  先看一个问题:

export function format(price) {
  return '¥' + price
}

// 下面代码报错
export function format(dateString) {
  return '2022-10-10'
}
方案 1
export function formatPrice(price) {
  return '¥' + price
}

export function formatDate(dateString) {
  return '2022-10-10'
}

  在早期,typescript 中是可以使用命名空间 namespace(内部模块) 来解决这个问题:

提示

  虽然 ts 命名空间还没有被弃用,但是 ES 模块已拥有命名空间的大部分特性,因此更加推荐使用 ES 模块(跟随时代发展,虽然一些旧的库中是存在使用命名空间的情况)

方案 2
// 模块化 + 命名空间
export namespace price {
  export function format(price) {
    return '¥' + price
  }
}

export namespace date {
  export function format(dateString) {
    return '2022-10-10'
  }
}
// 使用
import { price } from '..'

// price.format

# 二、声明文件.d.ts

# 类型声明

  除了.ts 文件外,还有.d.ts 文件 —— 用来只做类型声明(类型定义 Type Definition)的文件。

  那什么情况下需要使用.d.ts 文件呢?

编写第三方库的类型信息(当然,有的库是支持 ts 的,已经写好了.d.ts 文件)

根据需求提前声明一些全局性质的类型

├── types
    ├── index.ts
    ├── login.d.ts
    ├── AMap.d.ts
    └── others.d.ts

# 1、内置

const imgElm = document.querySelector('.pic') as HTMLImageElement

  关于 typescript 环境默认自带了哪些内置类型声明,详细可以查看:

https://github.com/microsoft/TypeScript/blob/main/src/lib/README.md

  具体包含的 API 集有:

  • ECMAScript 语言特性 - 例如 JavaScript API,如 Array 上的函数、Promise 等
  • DOM API - 例如 Web 浏览器中可用的 API,比如 Window、Document 等
  • ……

# 2、第三方

  关于我们使用的一些库,通常会有两种形式出现:

提示

  其实在最新的 npmjs.com 官网搜索 npm 包是,我们发现包的会有一个后缀:

  • TS(表示当前包已经编写了.d.ts 文件)
  • DT(提示当前包存在可下载的类型声明的包)
  • 方式 1:npm 后可以发现其库中已经进行了类型声明(编写了.d.ts 文件)
import type {  AxiosRequestConfig, AxiosInstance } from 'axios'

axios.createInstance(config: AxiosRequestConfig)
npm install lodash
npm i @types/lodash

# 3、自定义(declare)

declare module 和 declare namespace 的区别

官方描述:Namespaces (opens new window)Namespaces and Modules (opens new window)

  在 TypeScript 1.5 中,命名法已更改。“内部模块”现在是“命名空间”。“外部模块”现在只是“模块”,以符合 ECMAScript 2015 的术语。即 module X (相当于现在首选 namespace X )。

// (外部)模块
declare module "buffer"

// 内部模块 -> 命名空间
declare module NodeJS // 以前
declare namespace  NodeJS // 现在

# ① declare 模块

  下面我们以高德地图的 JS API 为例:

  • types / AMap.d.ts
declare module 'AMap'

// 或者

declare module 'AMap' {
  export plugin(name: string | Array<any>, callback: Function): void;
}

# ② declare 文件 ✍

  常见的,我们在全局中还会声明一些文件模块(下面以 vite 创建的项目为例):

在真实的脚手架项目中,对文件模块的声明往往不需要我们手动 declare 的

声明文件模块

  类似的声明,在 env.d.ts 中已经集成 /// <reference types="vite/client" />

vite 描述:client-types (opens new window)

  • types / Imgs.d.ts
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.svg'

declare module '*.jpg' {
  const src: string
  export default src
}

  关于 vue 文件的声明,在 .vscode/extensions.json 已经提示了可以安装的插件来进行辅助开发。

其中 Vue.vscode-typescript-vue-plugin (opens new window) 可以帮助我们读取未进行类型声明的.vue 文件,因此不对.vue 文件进行类型声明也可以。

// 如果安装了上述插件,不写下面文件声明也是可以的
declare module '*.vue' {
  import { DefineComponent } from 'vue'
  const component: DefineComponent

  export default component
}

# ③ declare 命名空间

  除了上面的几种情况,我们还可以会遇到引入 SDK 的情况,以 QQ 互联的 js JDK 为例:

  • 没有 import
<!-- QQ 互联 -->
<script
  src="http://connect.qq.com/qc_jssdk.js"
  data-appid="100556005"
  data-redirecturi="http://www.corho.com:8080/#/login/callback"
></script>

<!-- jQuery -->
<script src="https://unpkg.com/[email protected]/dist/jquery.js"></script>
  • types / index.d.ts
// 声明命名空间
declare namespace QC {
  export function init(appId: string, callback?: () => void): void
  export function login(params: any): void
  // 其他函数和对象的声明...
}

declare namespace $ {
  export function ajax(setting: any): any
}
开发应用
declare module 'three'
declare module '@/components/waves.vue'

declare interface Window {
  _AMapSecurityConfig: any
}

declare let $: JQuery
export default $
import 'pinia'
import type IMCore from '@/stores/plugin/IM-plugin/IM-core'

declare module 'pinia' {
  // store 中添加新的属性
  export interface PiniaCustomProperties {
    // IM核心功能
    timCore: IMCore
  }
}

# 三、tsconfig.json

官方手册:

TSConfig Reference (opens new window)

注意

  在开发中,我们更多的是使用 webpack 中的 ts-loader 进行打包时自动读取 tsconfig 文件,并根据配置来编译 Typescript 代码。

  并且更多时候,无论我们使用 Vue Cli 还是 Vite 创建项目时,选择了 Typescript 模板后,tsconfig 文件会默认帮我们配置好的。

# 顶层选项

{
  "compilerOptions": {
    //
  },
  "files": [], // 指定哪些ts文件需要进行编译
  "include": ["./src/**/*.ts", "./types/*.d.ts"], // 指定要编译哪些ts文件
  "exclude": ["node_modules"] // 指定要从includes中排除哪些文件
  // 其他
}

# 1、默认配置

  在 TypeScript 中,当将 strict 编译选项设置为 true 时,默认情况下不允许使用 any 类型,因为 any 类型相当于关闭了 TypeScript 对类型的检查,这与 strict 模式的目的相违背。

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,

    "strict": true,
    // "noImplicitAny": true,  /* ts编辑器无法推断变量类型,是否禁止🤔隐式 any 类型 */
    // "strictNullChecks": true,  /* 是否对可能为'null'和'undefined'的值进行检查 */

    "skipLibCheck": true
  }
}

  去官网,查阅一下,当"strict": true时,它包含了哪些配置?

答案

# 2、strict 模式 🎈

  关于"strict": true的体现(只选了常见的记录一下):

  • "noImplicitAny": true

提示

默认情况下,采用的是不允许存在 隐式 any 类型。开发中,可根据需要将其改为 false。

// 参数bar有警告
function foo(bar) {
  console.log(bar)
}
  • "strictNullChecks": true

提示

如果需要处理可能为 nullundefined 的变量,则可以使用可选链操作符 ? 或非空断言操作符 ! 进行处理。同理,开发中,可根据需要将其改为 false。

// 情况1
let str: string = null // 报错

// 情况2 🤔
let obj: { prop: string } | null = null
obj.prop // 报错 ---》 解决办法(可选链操作符):obj?.prop

// 情况3 🤔
let str: string | null = null
function foo(str: string) {
  console.log(str.length)
}
foo(str) // 报错 ---》 解决办法(非空断言操作符):foo(str!)

# 3、个性化配置

{
  "compilerOptions": {
    "rootDir": "./src", // 对指定目录文件进行编译(默认./)
    // "rootDir": "./",
    // "rootDirs": [],

    "outDir": "./dist" // 指定编译生成.js文件放置位置(默认./)
    // "outDir": "./",
  }
}

# 4、自动生成

官网描述:Project Configuration (opens new window)

# 1、生成tsconfig.json
tsc --init

默认配置:

更新于 : 8/7/2024, 2:16:31 PM