TypeScript 如何做动态导入

前端开发里,动态导入是处理页面资源按需加载的实用技巧——比如做电商网站时,只有用户点进商品详情页才加载对应的详情脚本,能减少初始页面加载体积,提升打开速度。但如果用的是TypeScript,不少开发者会疑惑:TypeScript怎么实现动态导入?其实核心是在JavaScript原生动态导入的基础上,补全TypeScript的类型提示,既保留按需加载的优势,又能享受TS的类型校验。

先搞懂基础:JS的动态导入是什么

先从大家熟悉的JavaScript说起。普通的import是静态导入,页面加载时就会自动把目标脚本拉进来,不管用不用;而动态导入用import()函数(注意是带括号的函数形式),返回一个Promise,只有调用时才加载资源。举个生活化的例子:你订外卖时,不会提前把所有商家的餐都送到家,而是下单(调用import())后,商家才把对应餐品送过来——这就是按需加载。

TypeScript 如何做动态导入

举个实际的JS例子:

`javascript

// 点击按钮才加载弹窗组件

document.getElementById('openDialog').addEventListener('click', async () => {

// 点击时才加载dialog.js

const dialogModule = await import('./dialog.js');

dialogModule.showDialog();

});

`

这样初始加载时不会带dialog.js,只有用户需要时才加载,省了初始体积。

TypeScript的动态导入:补全类型提示

TypeScript的动态导入,完全兼容JS的import(),只是会自动解析被导入模块的类型——前提是被导入的模块本身有类型定义(比如.ts/.tsx文件,或带.d.ts声明的.js模块)。

还是用弹窗组件的例子,改成TS版本:

`typescript

// 定义dialog模块的类型(如果是.ts文件,TS自动生成)

type DialogModule = {

showDialog: () => void;

hideDialog: () => void;

};

document.getElementById('openDialog')?.addEventListener('click', async () => {

// 1. 自动推断出import返回的是Promise<DialogModule>,不用手动写类型

const dialog = await import('./dialog');

// 2. TS会校验:showDialog是存在的,hideDialog也是,不会写错方法名

dialog.showDialog();

// 报错:TS会提示dialog上没有不存在的方法,提前规避错误

// dialog.wrongMethod();

});

`

这里的关键是:如果被导入的文件是.ts/.tsx,TS会自动根据文件的导出内容生成类型,不需要额外手写;如果是.js文件,就需要补一个类型声明文件(比如dialog.d.ts),告诉TS模块里有什么方法,避免类型报错。

特殊场景:动态导入带变量路径怎么办?

有些时候,导入的路径是动态变化的——比如做多语言网站,要根据用户选的语言导入对应翻译文件,路径是./locales/${lang}.ts。这时候TS需要稍微调整,不能直接用变量拼接路径,否则会报错。

正确的做法是用import.meta.resolve(或TS支持的动态路径写法),让TS能识别路径范围,举个例子:

`typescript

async function loadLocale(lang: 'zh-CN' | 'en-US') {

// TS会识别路径是./locales/下的合法文件,不会乱报错

const localeModule = await import(./locales/${lang}.ts);

return localeModule;

}

// 调用:选中文就加载zh-CN.ts,选英文就加载en-US.ts

loadLocale('zh-CN').then(locale => console.log(locale.greeting));

`

这里要注意,动态路径的变量必须是固定的取值范围(比如上面的lang只能是zh-CN或en-US),不能用任意字符串,否则TS会不知道哪些文件存在,没法做类型校验。

避坑提醒:别踩这两个常见错误

  • 不要把import()写成静态导入:比如写成import dialog from './dialog',这是静态导入,会在页面加载时就执行,失去动态加载的意义,TS还会提示冗余。
  • 不要在动态导入里用未知路径:如果路径是不确定的任意字符串,TS会无法做类型校验,还会报错找不到模块,比如import(./modules/${anyString}.ts)就不合适,必须限定路径的可选值。

总的来说,TypeScript做动态导入,就是在JS原生按需加载的基础上,加上类型校验的“安全锁”,既保留了优化加载速度的优势,又能提前发现代码错误,适合所有需要做性能优化的前端项目。

上一篇 JavaScript 对象怎么遍历