自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Umd 的包如何導(dǎo)出 TS 類型

開發(fā) 前端
現(xiàn)在 TypeScript 的模塊都是 es module 的方式引入的,但有一些包是支持 umd 的,它們可能用各種方式引入模塊,為了實現(xiàn) umd 模塊的類型檢查,可以用 declare global 把導(dǎo)出的變量變?yōu)槿值摹?/div>

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

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

export default Guang;

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

使用的時候用 import 來導(dǎo)入:

import Guang from 'xxx';

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

這樣是沒啥問題。

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

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

圖片

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

那如果你構(gòu)建出了 umd 規(guī)范的代碼,使用者用 script 的方式給引入了:

圖片

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

不能了,因為你導(dǎo)出是用的 esm 的 export,只有 import 引入才會有類型提示和對應(yīng)的檢查。

那怎么辦呢?

用 declare global 聲明為全局類型?

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

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

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

TypeScript 專門為這種情況設(shè)計個了語法,叫 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 里關(guān)掉。

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

圖片

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

圖片

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

圖片

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

總結(jié)

現(xiàn)在 TypeScript 的模塊都是 es module 的方式引入的,但有一些包是支持 umd 的,它們可能用各種方式引入模塊,為了實現(xiàn) umd 模塊的類型檢查,可以用 declare global 把導(dǎo)出的變量變?yōu)槿值摹?/p>

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

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

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

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

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

2022-04-17 10:29:10

TSTypeScript對象類型

2022-01-19 23:41:56

TS索引類型

2021-07-05 16:10:35

JavaScript代碼前端

2022-02-12 22:16:53

TypeScript類型字符串

2022-02-25 14:04:56

TS前端代碼

2022-04-29 06:54:48

TS 映射類型User 類型

2022-08-14 06:59:01

TS 類型編程索引類型

2022-08-26 10:01:48

Vue3TS

2022-05-07 07:33:55

TypeScript條件類型

2022-12-30 08:08:30

2023-12-01 08:54:50

Java原子類型

2023-06-13 18:24:26

TypeScriptJSDoc開發(fā)

2021-08-16 08:45:38

JavaScript開發(fā)代碼

2021-12-25 22:29:31

類型編程Javascript類型體操

2021-06-29 09:01:50

Swift閉包語言

2022-01-14 14:19:38

ReactTS前端

2024-12-30 09:03:09

2024-02-20 08:56:50

JavaScript模塊打包器

2010-12-31 15:22:26

郵箱數(shù)據(jù)

2024-08-19 09:07:09

TSvoid類型
點贊
收藏

51CTO技術(shù)棧公眾號