主頁 > 前端設計 > 在打字稿手冊中,提前生成實際上意味著什么?

在打字稿手冊中,提前生成實際上意味著什么?

2021-12-06 12:02:29 前端設計

打字稿手冊模板文字型別中,它說:

對于模板文字中的每個插值位置,聯合交叉相乘:

type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
type Lang = "en" | "ja" | "pt"; 
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;

然后它說:

我們通常建議人們對大型字串聯合使用提前生成,但這在較小的情況下很有用。

但什么是“超前一代”?最后一段是什么意思?因為他沒有舉個例子,所以我不太明白。

uj5u.com熱心網友回復:

為了獲得類似權威答案的內容,我查找了介紹此檔案的提交,將其追溯到具有類似措辭的TypeScript 4.1 發行說明提交

當您需要大量字串時,您應該考慮提前自動生成它們以節省每次型別檢查的作業

這兩個提交都是由@orta 撰寫的。在 TypeScript Discord 上問他最初來自哪里,它基本上來自@DanielRosenwasser 撰寫的 TS 開發博客,但 @orta 也編輯了文本。


因此,“提前生成”是用您選擇的語言撰寫一些代碼的行為(這可能是 TypeScript,但不一定是),當您提前運行它時會生成您想要的 TypeScript 代碼一次,一次。

因此,不是直接撰寫執行 X 的代碼,而是撰寫撰寫執行 X 的代碼的代碼。

這里的建議是,不要撰寫以下 TypeScript 代碼,

type EmailLocaleIDs = "welcome_email" | "email_heading";
type FooterLocaleIDs = "footer_title" | "footer_sendoff";
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
type Lang = "en" | "ja" | "pt";
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;

在編譯器必須評估LocaleMessageIDs聯合本身的情況下,您離開 TypeScript IDE 并轉到其他環境(例如不同的 TypeScript IDE)并撰寫以下代碼:

const locales = ["welcome_email", "email_heading", "footer_title", "footer_sendoff"];
const langs = ["en", "ja", "pt"];
console.log(
    "type LocaleMessageIDs = "  
    langs.map(lang =>
        locales.map(locale =>
            "\""   lang   "_"   locale   "_id\""
        ).join(" | ")
    ).join(" |\n    ")   ";"
);

運行此代碼時,控制臺會記錄以下內容:

type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" |
    "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" |
    "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id";

您可以將其復制并粘貼到原始 TypeScript IDE 中。

Playground 鏈接到代碼

在這兩種情況下,您最終都會得到一個LocaleMessageIDs型別,它是相同的十二個字串文字型別的聯合。但在第一種情況下,TypeScript 編譯器通過處理模板文字型別來評估聯合,而在第二種情況下,TypeScript 編譯器只需要直接決議字串文字。


對于簡單的小型聯合,例如LocaleMessageID進行任何型別的代碼生成都是非常愚蠢的。但是很容易將其更改為生成聯合的東西,這些聯合非常復雜,足以計算出編譯器性能嚴重下降。

這是一個名為 的型別的故意次優實作PalindromicFourteenBitString,任何字串只由"0"組成,"1"向前和向后相同:

type Binary = '1' | '0';

type BinaryLength<N extends number, L extends 0[] = [], O extends string = ""> =
    N extends L['length'] ? O : BinaryLength<N, [0, ...L], `${O}${Binary}`>;

type Reverse<T extends string, C extends string = ""> = 
    T extends `${infer F}${infer R}` ?
    Reverse<R, `${F}${C}`> : C;

type PalindromicFourteenBitString = BinaryLength<14> extends infer B ?
    B extends Reverse<Extract<B, string>> ? B : never : never;

這是一個次優的實作,因為我們生成每個長度為 14 的二進制字串并過濾掉任何不是回文的字串。有一個更好的方法來做到這一點(生成長度為 7 的字串并鏡像每個字串),但關鍵是想出一些需要一些計算來評估的東西。

無論如何,當您去測驗它時,您可能會注意到編譯器指出錯誤所在的行的速度很慢,如果您查看計算機的 CPU,它可能會非常努力地作業:

let b: PalindromicFourteenBitString; // ?? ??????
b = "10010011001001"; // okay
b = "10001011001001"; // error
b = "00110011001100"; // okay

Playground 鏈接到代碼

將此與執行代碼生成時發生的情況進行比較:

const palindromicFourteenBitStrings =
    Array.from({ length: 1 << 14 }, (_, i) => i.toString(2).padStart(14, "0"))
        .filter(s => s === s.split("").reverse().join(""));
console.log(
    "type PalindromicFourteenBitString =\n    "  
    palindromicFourteenBitStrings.map((x, i) => '"'   x   '"'  
        (i % 8 == 7 ? "\n   " : "")).join(" | "));

如果您運行它,它會輸出以下內容(并且很快):

type PalindromicFourteenBitString =
    "00000000000000" | "00000011000000" | "00000100100000" | "00000111100000" | "00001000010000" | "00001011010000" | "00001100110000" | "00001111110000"
    | "00010000001000" | "00010011001000" | "00010100101000" | "00010111101000" | "00011000011000" | "00011011011000" | "00011100111000" | "00011111111000"
    | "00100000000100" | "00100011000100" | "00100100100100" | "00100111100100" | "00101000010100" | "00101011010100" | "00101100110100" | "00101111110100"
    | "00110000001100" | "00110011001100" | "00110100101100" | "00110111101100" | "00111000011100" | "00111011011100" | "00111100111100" | "00111111111100"
    | "01000000000010" | "01000011000010" | "01000100100010" | "01000111100010" | "01001000010010" | "01001011010010" | "01001100110010" | "01001111110010"
    | "01010000001010" | "01010011001010" | "01010100101010" | "01010111101010" | "01011000011010" | "01011011011010" | "01011100111010" | "01011111111010"
    | "01100000000110" | "01100011000110" | "01100100100110" | "01100111100110" | "01101000010110" | "01101011010110" | "01101100110110" | "01101111110110"
    | "01110000001110" | "01110011001110" | "01110100101110" | "01110111101110" | "01111000011110" | "01111011011110" | "01111100111110" | "01111111111110"
    | "10000000000001" | "10000011000001" | "10000100100001" | "10000111100001" | "10001000010001" | "10001011010001" | "10001100110001" | "10001111110001"
    | "10010000001001" | "10010011001001" | "10010100101001" | "10010111101001" | "10011000011001" | "10011011011001" | "10011100111001" | "10011111111001"
    | "10100000000101" | "10100011000101" | "10100100100101" | "10100111100101" | "10101000010101" | "10101011010101" | "10101100110101" | "10101111110101"
    | "10110000001101" | "10110011001101" | "10110100101101" | "10110111101101" | "10111000011101" | "10111011011101" | "10111100111101" | "10111111111101"
    | "11000000000011" | "11000011000011" | "11000100100011" | "11000111100011" | "11001000010011" | "11001011010011" | "11001100110011" | "11001111110011"
    | "11010000001011" | "11010011001011" | "11010100101011" | "11010111101011" | "11011000011011" | "11011011011011" | "11011100111011" | "11011111111011"
    | "11100000000111" | "11100011000111" | "11100100100111" | "11100111100111" | "11101000010111" | "11101011010111" | "11101100110111" | "11101111110111"
    | "11110000001111" | "11110011001111" | "11110100101111" | "11110111101111" | "11111000011111" | "11111011011111" | "11111100111111" | "11111111111111";

如果你把輸出作為您的TS的源代碼及測驗的是,該編譯器的性能是非常快的,而且也沒有CPU秒殺發言:

let b: PalindromicFourteenBitString; ?? ??????
b = "10010011001001"; // okay
b = "10001011001001"; // error
b = "00110011001100"; // okay

Playground 鏈接到代碼

因此,這是一個示例,在此示例中,您將有更好的體驗來提前計算聯合,而不是要求 TypeScript 編譯器通過模板文字型別操作來完成。


當我問他那行檔案是什么意思時,@orta 詳細說明不應在模板字串文字型別中撰寫大型別函式,例如將GraphQL 查詢字串轉換為相應的型別。如果你想撰寫代碼來做到這一點,你應該用其他語言撰寫它并從它的輸出中生成 TypeScript 型別。


旁白:濫用編譯器來評估型別比代碼生成更糟糕的其他壞主意
  • 小于或等于某個值的素數元組

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/373503.html

標籤:打字稿

上一篇:如何將回應物件屬性從陣列轉換為請求rxjs

下一篇:Typescript React:使用propsAND(!)解構

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more