<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          TypeScript: 請(qǐng)停止使用 any

          共 3252字,需瀏覽 7分鐘

           ·

          2020-10-25 17:19


          本文譯自:https://thoughtbot.com/blog/typescript-stop-using-any-there-s-a-type-for-that

          當(dāng)我們開(kāi)發(fā) TypeScript 代碼時(shí),很可能會(huì)遇到 any 關(guān)鍵字。我們看到的大多數(shù)用法都表明我們正在處理 TypeScript 中的基本類型。在文檔中我們可能會(huì)找到:

          (…)來(lái)不使用 TypeScript 或第3方庫(kù)編寫(xiě)的代碼的值。在這些情況下,我們可能要選擇退出類型檢查。為此,我們將這些值標(biāo)記為 any 類型:

          什么是 any

          因此 any 不是通配符,也不是基類型,它是明確地與第三方庫(kù)進(jìn)行交互。那它為什么經(jīng)常出現(xiàn)你呢?它對(duì)我們的系統(tǒng)有害嗎?我們應(yīng)該逃避它還是擁抱它?

          any 類型是使用現(xiàn)有 JavaScript 的強(qiáng)大方法,可讓您在編譯期間逐漸選擇加入和選擇退出類型檢查。

          TypeScript 文檔明確表達(dá)了當(dāng)我們使用any類型時(shí),我們正在告訴編譯器:

          當(dāng)超過(guò)500名該語(yǔ)言的貢獻(xiàn)者提供幫助時(shí),我們說(shuō) no thank you。這聽(tīng)起來(lái)像是選擇退出類型檢查器,有了它,就不能輕易地放棄對(duì)類型系統(tǒng)的所有安全性和信心。我們應(yīng)該使用它來(lái)與無(wú)類型的第三方(或第一方) Javascript 代碼交互,或者當(dāng)我們只知道類型的一部分時(shí)。

          但是等等我還有很多其他原因

          TypeScript 不會(huì)轉(zhuǎn)換為 Javascript 嗎?Javascript 不是動(dòng)態(tài)的嗎?那我為什么要考慮我的類型呢?

          是的!但是我們用 TypeScript 寫(xiě)代碼,這是一種靜態(tài)類型語(yǔ)言。有人可能會(huì)說(shuō)靜態(tài)類型語(yǔ)言不會(huì)比動(dòng)態(tài)語(yǔ)言產(chǎn)生更少的 bug 。不過(guò),在使用 any 之類的靜態(tài)類型語(yǔ)言中,這是兩種情況中最糟糕的。

          有些參數(shù)很難正確輸入,但是 any 更容易

          如果我們沒(méi)有正確地輸入,我們將會(huì)編寫(xiě)錯(cuò)誤,比我們?cè)趧?dòng)態(tài)語(yǔ)言中會(huì)編寫(xiě)更多的錯(cuò)誤,因?yàn)槲覀儚?qiáng)制 TypeScript ,一種靜態(tài)類型語(yǔ)言,去檢查不正確的類型。

          我真的不知道參數(shù)是什么

          沒(méi)關(guān)系!我們可以用 unknown ; 它允許我們確實(shí)分配任何類型。但在確定特定類型之前,我們將不允許使用這些值。

          type?ParsedType?=?{
          ??id:?number
          }

          const?parseApiResponse(
          ??response:?Record
          ):?ParsedType?=>?{
          ??const?convertedResponse?=?(response?as?ParsedType)

          ??//?without?doing?the?type?cast?we?would
          ??//?get?a?type?error?here
          ??if(convertedResponse.id?>=?0)?{
          ????return?convertedResponse
          ??}?else?{
          ????throw?Error.new("Invalid?response"
          ??}
          }

          添加類型時(shí),我必須編寫(xiě)大量代碼,any工作量較少

          可能不是,如果編寫(xiě)的代碼沒(méi)有類型,則我們可能需要添加防御性代碼,以確保參數(shù)和變量具有正確的類型,以使程序能夠按預(yù)期執(zhí)行。any 甚至無(wú)法防范 nullundefined 檢查我們的邏輯 。

          //?version?1?with?`any`
          const?fullName?=?(user:?any)?=>?{
          ??if?(user?.firstName?&&?user?.lastName)?{
          ????return?`${user.lastName},?${user.firstName}`
          ??}

          ??return?user?.firstName?||?""
          }

          //?version?1?without?`any`

          interface?User?{
          ??firstName:?string
          ??lastName?:?string
          }

          const?fullName?=?({?firstName,?lastName?}:?User)?=>?{
          ??if?(lastName?===?undefined)?{
          ????return?firstName
          ??}

          ??return?`${lastName},?${firstName}`;
          }

          類型增加了很多復(fù)雜性,有時(shí)any更簡(jiǎn)單

          使用 any 可能允許我們?cè)诓豢紤]數(shù)據(jù)如何流入邏輯的情況下更簡(jiǎn)單的開(kāi)發(fā)。但它將這個(gè)負(fù)擔(dān)會(huì)轉(zhuǎn)移到我們代碼的未來(lái)讀者身上。他們將不得不在沒(méi)有上下文和編譯器幫助的情況下解釋發(fā)生了什么。

          有了文檔,我可以提供所有上下文

          添加類型時(shí),我們會(huì)從編譯器獲得幫助,并且會(huì)獲得不會(huì)隨時(shí)間推移而衰減的文檔,因?yàn)槿绻^(guò)時(shí)了,我們的代碼將無(wú)法編譯。

          const?intersection?=?(a:?any,?b:?any):?any?=>?{
          ...
          }
          const?intersection?=?(
          ??a:?Set,?b:?Set
          ):?Set?=>?{
          ...
          }

          它們都是等效的,但是讀者會(huì)更好地了解后面的函數(shù)在做什么,而不是從第一個(gè)函數(shù)開(kāi)始。

          我已經(jīng)通過(guò)必要的運(yùn)行時(shí)檢查以防御性的方式編寫(xiě)了代碼,以確保沒(méi)有錯(cuò)誤

          現(xiàn)在可能沒(méi)有錯(cuò)誤,但是除非你有很好的測(cè)試覆蓋率,否則以后來(lái)修改代碼的人不會(huì)相信他們不是在錯(cuò)誤中重構(gòu);就好像編譯器不會(huì)幫你,因?yàn)槲覀冋f(shuō)過(guò)它不會(huì)幫你。如果我們顯式地設(shè)置類型并更改系統(tǒng)中使用的API,編譯器將提供它的指導(dǎo)。

          如果以后我改變主意怎么辦?我可能會(huì)為此重構(gòu)幾個(gè)小時(shí)

          我們總是可以修改和適應(yīng)新的類型定義, TypeScript 為此提供了一組實(shí)用功能。我們可以 Pick 習(xí)慣從先前定義的類型中選擇所需的屬性。Omit 得到除少數(shù)幾個(gè)以外的所有東西。Partial 使所有屬性都是可選的,或進(jìn)行完整的180并使其全部Requireds。

          type?User?=?{
          ??id:?number;
          ??firstName:?string;
          ??lastName:?string;
          ??age:?number;
          }

          type?UserParams?=
          ??Pick"id">?&?Partial"id">>

          const?updateUser?=?(
          ??{?id,?...newUserParams?}:?UserParams
          )?=>?{
          ??{...}
          }

          很好,從TypeScript中刪除 any,立即打開(kāi)PR

          讓我們深吸一口氣, any 它在正確的情況下非常強(qiáng)大且有用。

          • 與使用它的庫(kù)接口;確保在將數(shù)據(jù)移至系統(tǒng)之前盡快將其轉(zhuǎn)換為正確的類型。

          • 解決 TypeScript 類型錯(cuò)誤;如果我們發(fā)現(xiàn)自己無(wú)法輸入某些內(nèi)容,則 any 可能有必要。但是只有在嘗試其他所有方法之后才推薦使用。如果使用它,我們應(yīng)該將其重新轉(zhuǎn)換為可預(yù)測(cè)的類型。

          • 如果我們的函數(shù)可以真正處理任何類型,那么這種情況很少見(jiàn),并且是偶然的(例如調(diào)試或日志記錄函數(shù))。在這些情況下,我們需要 100% 確保不存在會(huì)導(dǎo)致函數(shù)失敗的類型。我們應(yīng)該檢查函數(shù)的主體,并根據(jù)輸入確定最基本的形狀并加以限制。例如,如果我們要打印某些內(nèi)容,則至少應(yīng)驗(yàn)證它是否響應(yīng) toString

          讓我們回顧一下

          為什么我們不能在使用 any ?

          • 它使編譯器過(guò)時(shí)了,我們告訴編譯器:我不需要你的幫助
          • 我們放棄了在編寫(xiě)代碼時(shí)記錄代碼的機(jī)會(huì)
          • 我們的第一道防線被攻破了
          • 在動(dòng)態(tài)語(yǔ)言中,我們假設(shè)事物可以有 any 類型,我們采用的模式遵循這個(gè)假設(shè)。如果我們開(kāi)始使用靜態(tài)類型語(yǔ)言作為動(dòng)態(tài)語(yǔ)言,那么我們就是在與范式作斗爭(zhēng)
          • 當(dāng)我們繼續(xù)對(duì)代碼庫(kù)進(jìn)行更改時(shí),沒(méi)有什么可以指導(dǎo)/幫助我們。
          • 自由越大,責(zé)任越大(編譯器)。不要變成一個(gè)編譯器,我們的目的是使用編譯器。

          掃碼關(guān)注公眾號(hào),訂閱更多精彩內(nèi)容。



          你點(diǎn)的每個(gè)贊,我都認(rèn)真當(dāng)成了喜歡
          瀏覽 70
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  翔田千里无码乱伦 | 色欲影视淫色淫香 | 人人妻人人爽人人DVD | 三级片91| 中国黄色电影一级片 |