成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Umd 的包如何導出 TS 類型

開發 前端
現在 TypeScript 的模塊都是 es module 的方式引入的,但有一些包是支持 umd 的,它們可能用各種方式引入模塊,為了實現 umd 模塊的類型檢查,可以用 declare global 把導出的變量變為全局的。

在 TypeScript 里聲明模塊,最早是用 namespace 和 module 的語法,后來支持了 es module,類型和變量會用 import 來導入、用 export 導出。

比如你寫了一個庫,導出的變量叫 Guang,它下面有 name 和 age 兩個屬性,所以你是這樣聲明類型的:

export default Guang;

declare namespace Guang {
export const name = 'guang';
export const age = '20';
}

使用的時候用 import 來導入:

import Guang from 'xxx';

console.log(Guang.name, Guang.age);

這樣是沒啥問題。

但如果這個庫除了支持 es module 的方式使用,還支持 umd 呢?

UMD 規范想必大家很熟悉了,就是判斷是 CMD、AMD 還是全局變量的方式,然后用合適的模塊規范導出模塊的值:

圖片

但這里面不包含 es module,因為它不是 api 而是語法。

那如果你構建出了 umd 規范的代碼,使用者用 script 的方式給引入了:

圖片

這樣還能做類型提示和檢查么?

不能了,因為你導出是用的 esm 的 export,只有 import 引入才會有類型提示和對應的檢查。

那怎么辦呢?

用 declare global 聲明為全局類型?

declare global {
namespace Guang {
export const name = 'guang';
export const age = '20';
}
}

這樣是能解決問題,但這樣在 esm 模塊里也不用 import 就可以直接用了,而我們想在 esm 里用 import,其他情況才用全局類型。

有啥方式能約束在 esm 里只能 import 用,但是其他地方可以做為全局類型呢?

TypeScript 專門為這種情況設計個了語法,叫 export as namespace xxx;

比如上面的代碼可以這樣寫:

export = Guang;
export as namespace Guang;

declare namespace Guang {
export const name = 'guang';
export const age = '20';
}

export = Guang 是兼容老的 ts import 語法的,支持 umd 得加上這一行,然后加上 export as namespace Guang;

這樣你在非 esm 里就可以通過全局類型的方式使用它了:

圖片

而在 esm 里,如果也是這樣用的,它會報錯:

圖片

說是你在 esm 模塊里用了一個 UMD 的 global 類型,建議用 import 的方式代替。

如果你用 import 的方式引入了這個類型,就不報錯了:

圖片

這就是它比 declare global 好的地方,可以約束在 esm 里用 import 引入,非 es module 可以作為全局類型。

這樣就完美兼容了 esm 和 umd 兩種模塊引入方式。

而且如果你不想要這種限制,也可以在 tsconfig.json 里關掉。

有個 allowUmdGlobalAccess 的編譯選項就是控制是否支持在 es module 里使用 UMD 全局類型的:

圖片

默認是 false,開啟以后在 es module 里使用 UMD 全局類型就不報錯了:

圖片

很多庫都需要兼容 esm 和 umd 的使用方式都會這樣用,比如 react:

圖片

所以,如果你開發的庫需要支持 esm 和 umd 的話,可以用 export namespace as xxx 來導出,會比 declare global 更好。

總結

現在 TypeScript 的模塊都是 es module 的方式引入的,但有一些包是支持 umd 的,它們可能用各種方式引入模塊,為了實現 umd 模塊的類型檢查,可以用 declare global 把導出的變量變為全局的。

但是在 es module 里還是希望使用 import 引入,非 es module 才用全局類型,所以更好的方式是使用 export as namespace xxx。

用這種方式聲明的類型,當在非 esm 中使用時,會作為全局類型,而在 esm 中如果直接引用全局類型會報錯,建議用 import 引入。這是它比 declare global 更好的地方。

當然,也可以把 allowUmdGlobalAccess 的編譯選項設置為 true 來放開這種約束。

像 react 這種支持 umd 的庫都是用這種方式導出類型的,如果你也要開發一個支持 umd 的庫,不妨也試試 export as namespace 吧。

責任編輯:武曉燕 來源: 神光的編程秘籍
相關推薦

2022-04-17 10:29:10

TSTypeScript對象類型

2022-01-19 23:41:56

TS索引類型

2021-07-05 16:10:35

JavaScript代碼前端

2022-04-29 06:54:48

TS 映射類型User 類型

2022-02-25 14:04:56

TS前端代碼

2022-02-12 22:16:53

TypeScript類型字符串

2022-05-07 07:33:55

TypeScript條件類型

2022-12-30 08:08:30

2023-06-13 18:24:26

TypeScriptJSDoc開發

2022-08-14 06:59:01

TS 類型編程索引類型

2022-08-26 10:01:48

Vue3TS

2023-12-01 08:54:50

Java原子類型

2021-08-16 08:45:38

JavaScript開發代碼

2022-01-14 14:19:38

ReactTS前端

2021-12-25 22:29:31

類型編程Javascript類型體操

2021-06-29 09:01:50

Swift閉包語言

2024-12-30 09:03:09

2022-04-19 21:05:03

JavaScript內置工具

2024-08-19 09:07:09

TSvoid類型

2024-02-20 08:56:50

JavaScript模塊打包器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: a网站在线观看 | 国产高清在线精品 | 国产在线一级片 | 成人在线精品视频 | 自拍视频网站 | 日本一区二区三区在线观看 | 国产黄色小视频在线观看 | 日本a v在线播放 | 国内激情av片| 在线观看久草 | 激情一区二区三区 | 免费av手机在线观看 | 国产黄色大片在线免费观看 | 毛片视频网站 | 欧美成人手机在线 | 欧美 日韩 国产 在线 | 国产欧美一区二区三区在线看蜜臀 | 国产激情在线 | 午夜精品一区二区三区免费视频 | 亚洲一区二区免费电影 | 国产极品粉嫩美女呻吟在线看人 | 免费在线视频精品 | 黄色大片在线播放 | 亚洲精品久久久一区二区三区 | 懂色一区二区三区免费观看 | 国产福利二区 | 97超碰站 | 日本在线免费观看 | av网站观看| 一级毛片免费 | av午夜电影 | 日本五月婷婷 | av黄色在线观看 | 国产精品久久久久久婷婷天堂 | 亚洲一二三在线观看 | 丁香六月伊人 | 欧美伦理一区 | 男人的天堂亚洲 | 欧美日韩久久久 | 天天久久 | 国产精品日产欧美久久久久 |