則詳解:強(qiáng)制 `typeof` 比較使用合法字符串字面量)
ESLint valid-typeof 規(guī)則詳解強(qiáng)制typeof比較使用合法字符串字面量【免費(fèi)下載鏈接】eslintFind and fix problems in your JavaScript code.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/es/eslinttypeof是 JavaScript 中判斷變量類型最常用的運(yùn)算符但它的返回值永遠(yuǎn)是固定的幾個(gè)字符串。將typeof的結(jié)果與拼寫錯(cuò)誤的字符串如strnig、undefimed進(jìn)行比較是日常開發(fā)中高頻出現(xiàn)的低級筆誤這類錯(cuò)誤不會(huì)導(dǎo)致運(yùn)行時(shí)崩潰卻會(huì)讓類型判斷邏輯靜默失效。ESLint 內(nèi)置的valid-typeof規(guī)則正是為攔截這類問題而設(shè)計(jì)它強(qiáng)制要求typeof表達(dá)式只能與合法的類型字符串字面量進(jìn)行比較并可選擇性地開啟requireStringLiterals選項(xiàng)進(jìn)一步要求比較對象必須是字符串字面量。讀完本文你將掌握該規(guī)則的完整配置方法、全部選項(xiàng)語義、源碼級判定邏輯以及適用邊界能夠把它正確接入自己的 ESLint 配置并理解底層實(shí)現(xiàn)。規(guī)則概述為什么需要校驗(yàn)typeof的比較值typeof運(yùn)算符對絕大多數(shù)使用場景返回以下 8 種字符串字面量之一undefinedobjectbooleannumberstringfunctionsymbolbigint將typeof表達(dá)式的結(jié)果與其他字符串字面量比較通常屬于輸入筆誤。例如typeof foo strnig在運(yùn)行時(shí)永遠(yuǎn)為false因?yàn)閠ypeof永遠(yuǎn)不會(huì)返回strnig這個(gè)值程序卻不會(huì)拋出任何錯(cuò)誤問題會(huì)被無聲地帶入線上。valid-typeof規(guī)則的核心職責(zé)就是保證typeof的比較對象限定在上述合法字符串集合內(nèi)相關(guān)定義見 lib/rules/valid-typeof.js 中的VALID_TYPES集合。在 ESLint 元信息中該規(guī)則被標(biāo)記為type: problem屬于“問題類”規(guī)則用于捕獲可能導(dǎo)致程序行為錯(cuò)誤的代碼模式recommended: true已被納入eslint:recommended推薦配置集開箱即用無需顯式聲明見 lib/rules/valid-typeof.js 及元數(shù)據(jù) docs/src/_data/rules_meta.jsonhasSuggestions: true支持提供編輯器可一鍵應(yīng)用的自動(dòng)修復(fù)建議見下文“自動(dòng)修復(fù)建議”一節(jié)。規(guī)則細(xì)節(jié)匹配的語法結(jié)構(gòu)該規(guī)則作用于typeof一元表達(dá)式與其外層二元比較表達(dá)式的組合。它只關(guān)注以下四種比較運(yùn)算符、、!、!源碼中通過OPERATORS集合定義見 lib/rules/valid-typeof.js。從源碼的監(jiān)聽邏輯看UnaryExpression訪問器見 lib/rules/valid-typeof.js規(guī)則按以下分支處理若typeof表達(dá)式的兄弟節(jié)點(diǎn)是字符串字面量或靜態(tài)模板字面量則取出其字面量值與VALID_TYPES集合比對不在集合內(nèi)即報(bào)告invalidValue“Invalid typeof comparison value.”若兄弟節(jié)點(diǎn)是標(biāo)識(shí)符undefined且確為未聲明的全局引用則報(bào)告錯(cuò)誤并給出把undefined替換為undefined的修復(fù)建議若開啟了requireStringLiterals且兄弟節(jié)點(diǎn)既不是字符串字面量也不是另一個(gè)typeof表達(dá)式則報(bào)告notString“Typeof comparisons should be to string literals.”。值得注意的是typeof foo baz與普通變量比較在默認(rèn)配置下是合法的——規(guī)則默認(rèn)不干預(yù)這類比較因?yàn)樽兞縝az的值可能在運(yùn)行時(shí)才是確定的字符串只有開啟requireStringLiterals后這類寫法才會(huì)被禁止。錯(cuò)誤示例以下代碼違反了默認(rèn)規(guī)則比較值不是合法類型字符串/*eslint valid-typeof: error*/ typeof foo strnig typeof foo undefimed typeof bar ! nunber typeof bar ! fucntion正確示例以下代碼在默認(rèn)規(guī)則下完全合法/*eslint valid-typeof: error*/ typeof foo string typeof bar undefined typeof foo baz typeof bar typeof qux注意后兩行typeof foo baz是與變量比較typeof bar typeof qux是兩個(gè)typeof表達(dá)式互比默認(rèn)配置下均被允許。選項(xiàng)配置該規(guī)則接受一個(gè)對象選項(xiàng)schema 見 lib/rules/valid-typeof.js默認(rèn)值見 lib/rules/valid-typeof.js選項(xiàng)類型默認(rèn)值說明requireStringLiteralsbooleanfalse為true時(shí)typeof表達(dá)式只能與字符串字面量或其他typeof表達(dá)式比較禁止與任何其他值比較requireStringLiterals: true開啟后規(guī)則會(huì)額外收緊比較對象任何非字符串字面量、非typeof表達(dá)式的比較值都會(huì)報(bào)錯(cuò)包括undefined、Object、數(shù)字、普通變量等。開啟該選項(xiàng)后的錯(cuò)誤示例/*eslint valid-typeof: [error, { requireStringLiterals: true }]*/ typeof foo undefined typeof bar Object typeof baz strnig typeof qux some invalid type typeof baz anotherVariable typeof foo 5開啟該選項(xiàng)后的正確示例/*eslint valid-typeof: [error, { requireStringLiterals: true }]*/ typeof foo undefined typeof bar object typeof baz string typeof bar typeof qux典型場景中typeof foo undefined是常見的錯(cuò)誤寫法foo未聲明時(shí)會(huì)拋ReferenceError聲明為null或undefined時(shí)比較結(jié)果也不符合預(yù)期正確寫法是typeof foo undefined。這也是該選項(xiàng)最有價(jià)值的使用場景。默認(rèn)配置下的一個(gè)特殊分支全局undefined標(biāo)識(shí)符即使不開啟requireStringLiterals規(guī)則仍會(huì)攔截一種隱蔽的寫法——把裸標(biāo)識(shí)符undefined直接與typeof表達(dá)式比較例如if (typeof bar ! undefined) {}源碼通過isReferenceToGlobalVariable判斷見 lib/rules/valid-typeof.js只有當(dāng)undefined是全局作用域中未在源碼內(nèi)聲明的變量引用時(shí)才報(bào)告因此function f(undefined) { typeof x undefined }這類把undefined作為局部參數(shù)名的寫法不會(huì)誤報(bào)對應(yīng)測試見 tests/lib/rules/valid-typeof.js。自動(dòng)修復(fù)建議對于上述undefined比較規(guī)則提供名為suggestString的修復(fù)建議見 lib/rules/valid-typeof.js 與 lib/rules/valid-typeof.js可自動(dòng)將裸標(biāo)識(shí)符替換為字符串字面量。默認(rèn)配置下報(bào)告invalidValue消息并附建議開啟requireStringLiterals時(shí)報(bào)告notString消息同樣附帶建議。測試中驗(yàn)證的修復(fù)結(jié)果為見 tests/lib/rules/valid-typeof.js// 修復(fù)前 typeof foo undefined // 修復(fù)后 typeof foo undefined需要說明的是這是“建議suggestion”而非“修復(fù)fix”在編輯器或--fix模式下需要顯式接受不會(huì)靜默改寫代碼。邊界與細(xì)節(jié)模板字面量、寫法方向與比較運(yùn)算符從測試用例tests/lib/rules/valid-typeof.js中可以梳理出規(guī)則對各類寫法的處理邊界靜態(tài)模板字面量同樣受檢typeof foo string合法而typeof bar umdefined會(huì)報(bào)invalidValue見 tests/lib/rules/valid-typeof.js 與 tests/lib/rules/valid-typeof.js動(dòng)態(tài)模板字面量不算靜態(tài)值typeof foo str${somethingElse}在默認(rèn)配置下合法因?yàn)槠渲翟谶\(yùn)行時(shí)才能確定但開啟requireStringLiterals后會(huì)報(bào)notString見 tests/lib/rules/valid-typeof.js 與 tests/lib/rules/valid-typeof.js比較方向無關(guān)strnig typeof foo與typeof foo strnig同樣會(huì)被檢查見 tests/lib/rules/valid-typeof.js四種比較運(yùn)算符全覆蓋、、!、!均納入檢查帶括號(hào)的寫法正常識(shí)別typeof(foo) string等寫法不會(huì)被漏檢見 tests/lib/rules/valid-typeof.js非比較用途不干預(yù)typeof foo thing這類拼接運(yùn)算不屬于比較場景規(guī)則不檢查見 tests/lib/rules/valid-typeof.jssymbol與bigint同樣合法這兩個(gè)較新的類型字符串已包含在VALID_TYPES中見 lib/rules/valid-typeof.js。如何啟用與配置由于該規(guī)則在recommended: true中使用官方推薦配置即可直接生效// eslint.config.js export default [ { rules: { valid-typeof: error, // 或使用對象選項(xiàng) valid-typeof: [error, { requireStringLiterals: true }], }, }, ];也可以直接繼承eslint:recommended或eslint/js的recommended配置無需顯式書寫該規(guī)則倉庫中推薦配置的集成測試見 tests/conf/eslint-recommended.js。何時(shí)關(guān)閉該規(guī)則如果項(xiàng)目會(huì)在宿主對象host objects如瀏覽器或 Node.js 運(yùn)行時(shí)提供的對象上使用typeof運(yùn)算符可以考慮關(guān)閉此規(guī)則。宿主對象的typeof行為不受 ECMAScript 規(guī)范約束某些環(huán)境下可能返回超出標(biāo)準(zhǔn)集合的字符串例如舊版瀏覽器中某些宿主對象返回unknown此時(shí)強(qiáng)制校驗(yàn)合法字符串會(huì)引入誤報(bào)。對這類邊界場景可通過規(guī)則配置按文件或目錄局部關(guān)閉。小結(jié)valid-typeof是一個(gè)低誤報(bào)、高價(jià)值的內(nèi)置問題類規(guī)則默認(rèn)即可捕獲拼寫錯(cuò)誤如strnig、undefimed導(dǎo)致的靜默失效比較requireStringLiterals: true可進(jìn)一步杜絕與裸undefined、構(gòu)造器、普通變量等非字面量的比較建議在嚴(yán)格類型檢查的團(tuán)隊(duì)規(guī)范中開啟規(guī)則的判定邏輯集中實(shí)現(xiàn)在 lib/rules/valid-typeof.js完整行為矩陣可對照測試文件 tests/lib/rules/valid-typeof.js 驗(yàn)證。將它與 ESLint 的推薦配置一起使用能有效減少 JavaScript 類型判斷代碼中最常見的那一類“不報(bào)錯(cuò)但永遠(yuǎn)不成立”的隱蔽缺陷。【免費(fèi)下載鏈接】eslintFind and fix problems in your JavaScript code.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/es/eslint創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考