詳解如何在TypeScript中聲明全局變量
有時(shí)候,你可能想在 TypeScript 使用一些自定義全局變量。例如,在我的一些 Web 應(yīng)用程序中,我需要將一些從服務(wù)器端渲染時(shí)傳遞過來的屬性給在瀏覽器中運(yùn)行的 JavaScript 代碼使用。為了做到這一點(diǎn),通常我會在內(nèi)聯(lián)腳本中定義一個(gè)名為 __INITIAL_DATA__ 的全局變量,并將一個(gè) JSON 序列化對象賦值給它:
<script>
window.__INITIAL_DATA__ = {
userID: "536891193569405430",
};
</script>現(xiàn)在,如果我嘗試在一個(gè) TypeScript 文件中訪問 window.__INITIAL_DATA__ 時(shí),編譯器就會產(chǎn)生一個(gè)類型錯(cuò)誤,因?yàn)樗也坏?__INITIAL_DATA__ 屬性的定義。
// Property '__INITIAL_DATA__' does not exist // on type 'Window & typeof globalThis' const initialData = window.__INITIAL_DATA__;
接下來,我將向你展示幾種不同的方法,讓 TypeScript 知道 window.__INITIAL_DATA__ 屬性的存在,并消除類型錯(cuò)誤。
使用類型斷言
消除類型錯(cuò)誤的最快方法是在類型斷言中使用 any 類型。我們可以將 window 對象視為任意類型,以便訪問其 __INITIAL_DATA__ 屬性:
const initialData = (window as any).__INITIAL_DATA__;
這個(gè)解決方案有效,我們不再遇到類型錯(cuò)誤。如果你需要一種臨時(shí)的方式來訪問 TypeScript 不知道的 window 對象上的屬性,這是一個(gè)實(shí)用的方法。
(window as any).__INITIAL_DATA__ 表達(dá)式是任意類型,因此 initialData 也是任意類型。我們可以進(jìn)一步使用另一種類型斷言來給 initialData 變量指定更具體的類型:
type InitialData = {
userID: string;
};
const initialData = (window as any).__INITIAL_DATA__ as InitialData;現(xiàn)在,我們可以以類型安全的方式訪問 initialData.userID :
const userID = initialData.userID; // string 類型
請記住,這并不保證 window.__INITIAL_DATA__ 在運(yùn)行時(shí)會被正確設(shè)置。類型檢查器相信我們,并且我們的工作是確保將一個(gè)符合預(yù)期形狀的對象賦值給 window.__INITIAL_DATA__ 。
聲明一個(gè)全局變量
另一種方法是使用 declare var 語法聲明一個(gè)全局變量。這樣,我們可以讓 TypeScript 找到這個(gè)具有給定名稱和類型的全局變量:
declare var __INITIAL_DATA__: InitialData;
我們現(xiàn)在可以直接訪問 __INITIAL_DATA__ 變量了……
const initialData = __INITIAL_DATA__;
……或通過 window 對象獲?。?/p>
const initialData = window.__INITIAL_DATA__;
有一點(diǎn)要注意的是,在ECMAScript模塊內(nèi)部通過 declare var 聲明的變量是是無法通過 window.__INITIAL_DATA__ 形式訪問的,會收到類型錯(cuò)誤。而所謂 ECMAScript 模塊就是包含頂級 import 或 export 聲明的那些文件。
你可以使用 declare global { ... } 語法在全局作用域中聲明一個(gè)全局變量,以便能夠在 JavaScript 模塊內(nèi)部或外部文件通過 window.__INITIAL_DATA__ 和 __INITIAL_DATA__ 兩種形式訪問。
export function someExportedFunction() {
// ...
}
declare global {
var __INITIAL_DATA__: InitialData;
}
const initialData = window.__INITIAL_DATA__;如果你需要在多個(gè)文件或模塊中訪問 window.__INITIAL_DATA__ ,那么在項(xiàng)目中創(chuàng)建一個(gè) globals.d.ts 文件可能是個(gè)好主意。在這個(gè)文件中,你可以聲明所有將要使用的全局變量:
declare var __INITIAL_DATA__: InitialData;
增強(qiáng) Window 接口
最后,你可以使用TypeScript 的接口聲明合并來告訴編譯器在 Window 類型上有一個(gè)名為 __INITIAL_DATA__ 的屬性。為了做到這一點(diǎn),你需要定義一個(gè)名為 Window 的接口,設(shè)置一個(gè)名為 __INITIAL_DATA__ 的屬性:
interface Window {
__INITIAL_DATA__: InitialData;
}TypeScript 將會上面的這個(gè)接口定義和 lib.dom.d.ts 中定義的 Window 接口合并,從而得到一個(gè)單一的 Window 類型。這樣一來,下面的賦值就不再產(chǎn)生類型錯(cuò)誤了:
const initialData = window.__INITIAL_DATA__;
請注意,這種方法同樣 ECMAScript 模塊中不起作用。為了使 window.__INITIAL_DATA__ 表達(dá)式能夠正確進(jìn)行類型檢查,需要再次使用 declare global { ... } 語法:
export function someExportedFunction() {
// ...
}
declare global {
interface Window {
__INITIAL_DATA__: InitialData;
}
}
const initialData = window.__INITIAL_DATA__;以上就是詳解如何在TypeScript中聲明全局變量的詳細(xì)內(nèi)容,更多關(guān)于TypeScript聲明全局變量的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript關(guān)于“時(shí)間”的一次探索
這篇文章主要介紹了javascript關(guān)于“時(shí)間”的一次探索,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
ES6中Set和Map數(shù)據(jù)結(jié)構(gòu)的簡單講解
大家心里是否產(chǎn)生過這樣的疑問,JS中既然已經(jīng)有對象這種數(shù)據(jù)結(jié)構(gòu),我們?yōu)槭裁催€要再單獨(dú)去使用Set或者M(jìn)ap呢?下面這篇文章主要給大家介紹了關(guān)于ES6中Set和Map數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2022-08-08

