最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript模板字面量類型高級用法示例代碼

 更新時間:2026年03月30日 09:54:22   作者:兆子龍  
TypeScript的字符串模板字面量類型結(jié)合字符串操作類型和鍵重映射,為我們提供了強大的工具,能夠在運行時創(chuàng)建新對象的類型,使高級JavaScript對象的創(chuàng)建更加健壯,這篇文章主要介紹了TypeScript模板字面量類型高級用法的相關(guān)資料,需要的朋友可以參考下

一、模板字面量類型是什么

模板字面量類型是 TypeScript 4.1 引入的強大特性,它允許你在類型層面使用類似 JavaScript 模板字符串的語法。通過這個特性,你可以基于已有的字符串類型構(gòu)造出新的字符串類型,實現(xiàn)精確的類型推導(dǎo)和約束。

在介紹具體用法之前,讓我們先理解模板字面量類型的基本語法:

type Greeting = `Hello, ${string}`;
const greeting1: Greeting = 'Hello, World';  // ? 正確
const greeting2: Greeting = 'Hi, there';     // ? 錯誤,不匹配模式

Greeting 類型表示所有以「Hello, 」開頭的字符串。只有符合這個模式的字符串才能賦值給 Greeting 類型的變量。

二、模板字面量類型的基本用法

2.1 字符串拼接類型

模板字面量類型最基礎(chǔ)的用法是拼接字符串:

type Part1 = 'Hello';
type Part2 = 'World';
type Greeting = `${Part1} ${Part2}`;
// Greeting 類型為 "Hello World"

2.2 使用聯(lián)合類型

模板字面量類型可以與聯(lián)合類型配合使用,生成所有可能的組合:

type Direction = 'top' | 'bottom' | 'left' | 'right';
type MarginProperty = `margin${Capitalize<Direction>}`;
// MarginProperty 類型為 "marginTop" | "marginBottom" | "marginLeft" | "marginRight"
type BorderProperty = `border${Capitalize<Direction>}-width`;
// BorderProperty 類型為 "borderTop-width" | "borderBottom-width" | ...

注意這里使用了 TypeScript 內(nèi)置的 Capitalize 工具類型,它可以將字符串類型的首字母轉(zhuǎn)為大寫。

2.3 內(nèi)置工具類型

TypeScript 提供了幾個與模板字面量類型配合使用的內(nèi)置工具類型:

  • Uppercase<StringType>:將字符串轉(zhuǎn)為大寫
  • Lowercase<StringType>:將字符串轉(zhuǎn)為小寫
  • Capitalize<StringType>:將首字母轉(zhuǎn)為大寫
  • Uncapitalize<StringType>:將首字母轉(zhuǎn)為小寫
type EventName = 'click' | 'hover' | 'focus';
type UpperEventName = `${Uppercase<EventName>}`;
// "CLICK" | "HOVER" | "FOCUS"
type HandlerName = `on${Capitalize<EventName>}`;
// "onClick" | "onHover" | "onFocus"

三、實戰(zhàn):CSS 屬性類型生成

讓我們通過一個實際場景來深入理解模板字面量類型的用法。假設(shè)我們需要為 CSS 屬性生成對應(yīng)的類型定義:

// 定義所有可能的 CSS 屬性前綴
type CssPropertyPrefix = '' | 'webkit' | 'moz' | 'ms' | 'o';
// 定義屬性名
type CssPropertyName = 
  | 'transform' | 'transition' | 'animation'
  | 'flex' | 'grid';
// 生成完整的 CSS 屬性名
type CssProperty = `${CssPropertyPrefix}${Capitalize<CssPropertyName>}`;
// 結(jié)果:"" | "WebkitTransform" | "MozTransform" | "MsTransform" | "OTransform" | ...

更復(fù)雜的例子,生成帶值的 CSS 屬性類型:

type CssValue = 'auto' | '0' | '100%' | '1px' | '2px';
type CssPropertyWithValue = `${CssProperty} ${CssValue}`;
// 例如:"transform auto" | "transform 0" | "WebkitTransform 100%" | ...

四、模板字面量類型與infer

模板字面量類型最強大的用法是配合 infer 關(guān)鍵字進行模式匹配和類型提?。?/p>

4.1 提取字符串中的特定部分

// 提取事件名稱
type ExtractEventName<T> = T extends `on${infer Name}` ? Name : never;
type ClickEvent = ExtractEventName<'onClick'>;      // "Click"
type HoverEvent = ExtractEventName<'onHover'>;      // "Hover"
type CustomEvent = ExtractEventName<'onCustom'>;    // "Custom"

4.2 提取路徑中的文件名

type ExtractFileName<T> = T extends `${string}/${infer Name}` ? Name : T;
type FileName1 = ExtractFileName<'/src/components/Button.tsx'>;  // "Button.tsx"
type FileName2 = ExtractFileName<'index.ts'>;                    // "index.ts"

4.3 提取駝峰命名并轉(zhuǎn)換

type CamelToKebab<T extends string> = 
  T extends `${infer First}${infer Rest}`
    ? First extends Uppercase<First>
      ? `-${Lowercase<First>}${CamelToKebab<Rest>}`
      : `${First}${CamelToKebab<Rest>}`
    : T;
type KebabCase = CamelToKebab<'backgroundColor'>;  // "background-color"
type KebabCase2 = CamelToKebab<'borderRadius'>;    // "border-radius"

4.4 提取并轉(zhuǎn)換 URL 參數(shù)

type ExtractQueryParams<T extends string> = 
  T extends `${string}?${infer Query}`
    ? Query extends `${infer Key}=${infer Value}&${infer Rest}`
      ? { [K in Key]: Value } & ExtractQueryParams<`?${Rest}`>
      : Query extends `${infer Key}=${infer Value}`
        ? { [K in Key]: Value }
        : {}
    : {};
type Params = ExtractQueryParams<'/api/users?id=1&name=jack&age=25'>;
// { id: "1" } & { name: "jack" } & { age: "25" }

五、模板字面量類型在React中的應(yīng)用

5.1 組件 Props 類型推導(dǎo)

type Size = 'small' | 'medium' | 'large';
type Color = 'primary' | 'secondary' | 'danger';
type ButtonVariant = `${Size}-${Color}`;
// "small-primary" | "small-secondary" | "small-danger" | ...
interface ButtonProps {
  variant: ButtonVariant;
  onClick: `handle${Capitalize<ButtonVariant>}`;
// 例如:handleSmallPrimary | handleSmallSecondary | ...
}
function createHandler(variant: ButtonVariant): ButtonProps['onClick'] {
  return `handle${variant}` as ButtonProps['onClick'];
}

5.2 狀態(tài)更新函數(shù)類型

type Setter<T extends string> = `set${Capitalize<T>}`;
interface State {
  name: string;
  age: number;
  email: string;
}
type StateSetters = {
  [K in keyof State as Setter<string & K>]: (value: State[K]) => void
};
// Setter<"name"> = "setName"
// 結(jié)果類型:{ setName: (value: string) => void; setAge: (value: number) => void; ... }

5.3 路由參數(shù)類型

type RouteParams<T extends string> = 
  T extends `${string}:${infer Param}/${infer Rest}`
    ? { [K in Param]: string } & RouteParams<`/${Rest}`>
    : T extends `${string}:${infer Param}`
      ? { [K in Param]: string }
      : {};
type BlogRoute = RouteParams<'/blog/:id/:slug'>;
// { id: string } & { slug: string }
type UserRoute = RouteParams<'/users/:id'>;
// { id: string }

六、模板字面量類型與映射類型

模板字面量類型可以與映射類型結(jié)合,批量生成相關(guān)的類型:

type APIResponse = {
  code: number;
  message: string;
  data: unknown;
};
type APIAction = 'login' | 'register' | 'logout' | 'profile';
type APIEndpoint = `/${APIAction}`;
type APIResponses = {
  [K in APIAction as `${K}${string}`]: APIResponse;
};
// 結(jié)果:
// {
//   login: APIResponse;
//   loginSuccess: APIResponse;
//   loginFailed: APIResponse;
//   register: APIResponse;
//   ...
// }

更實用的例子,生成表單驗證規(guī)則類型:

type ValidationRule = 'required' | 'minLength' | 'maxLength' | 'pattern';
type FieldName = 'email' | 'password' | 'username' | 'phone';
type ValidationConfig = {
  [F in FieldName as `${F}${Capitalize<ValidationRule>}`]: 
    F extends 'email' 
      ? { pattern: RegExp } | { required: true }
      : F extends 'password'
        ? { minLength: number } | { required: true }
        : { required: true } | { minLength: number; maxLength: number }
};
// emailRequired: { pattern: RegExp } | { required: true }
// passwordMinLength: { minLength: number } | { required: true }
// usernameRequired: { required: true } | { minLength: number; maxLength: number }

七、模板字面量類型的性能考慮

模板字面量類型在編譯時計算,過度復(fù)雜的類型推導(dǎo)可能會影響 TypeScript 的編譯性能。以下是一些優(yōu)化建議:

首先,避免在模板字面量類型中使用過深的遞歸。深度遞歸的類型推導(dǎo)會顯著增加類型檢查的時間。

// 不推薦:深層遞歸
type DeepCamelToKebab<T extends string, Acc extends string = ''> = 
  T extends `${infer First}${infer Rest}`
    ? First extends Uppercase<First>
      ? DeepCamelToKebab<Rest, `${Acc}-${Lowercase<First>}`>
      : DeepCamelToKebab<Rest, `${Acc}${First}`>
    : Acc;
// 推薦:限制遞歸深度或使用條件類型簡化
type SimpleCamelToKebab<T extends string> = 
  T extends `${infer A}${infer B}`
    ? A extends Uppercase<A>
      ? `-${Lowercase<A>}${SimpleCamelToKebab<B>}`
      : `${A}${SimpleCamelToKebab<B>}`
    : T;

其次,使用 extends 約束來縮小類型范圍,減少類型計算量:

// 不推薦:無約束的類型推導(dǎo)
type ExtractFromString<T> = T extends `${string}${infer Rest}` ? Rest : T;
// 推薦:添加約束
type ExtractFromString<T extends string> = 
  T extends `${string}${infer Rest}` ? Rest : T;

第三,對于復(fù)雜的類型計算,考慮使用類型別名緩存結(jié)果:

// 緩存計算結(jié)果
type CachedKebabCase<T extends string> = KebabCaseMap[T];
// 預(yù)先計算映射
type KebabCaseMap = {
  backgroundColor: 'background-color';
  borderRadius: 'border-radius';
  color: 'color';
  // ... 更多預(yù)計算的類型
};

八、模板字面量類型的調(diào)試技巧

復(fù)雜的模板字面量類型往往難以調(diào)試。以下是幾個實用的調(diào)試技巧:

第一個技巧是使用中間類型別名來分解復(fù)雜類型:

// 原始復(fù)雜類型
type ComplexType = `${Prefix}${Capitalize<Name>}${Suffix}`;
// 分解為多個中間類型
type Step1 = Capitalize<Name>;
type Step2 = `${Prefix}${Step1}`;
type Step3 = `${Step2}${Suffix}`;

第二個技巧是使用條件類型產(chǎn)生錯誤信息:

// 通過錯誤信息查看實際類型
type Debug<T> = T extends string ? never : T;
type Result = Debug<YourComplexType>;  // 錯誤信息會顯示實際類型

第三個技巧是使用 typeof 和模板字面量類型結(jié)合:

const config = {
  apiUrl: 'https://api.example.com',
  version: 'v1',
} as const;
type Endpoint = `${typeof config.apiUrl}/${typeof config.version}/${string}`;
// "https://api.example.com/v1/${string}"

九、常見問題與解決方案

9.1 模板字面量類型不生效

確保你使用的是 TypeScript 4.1 或更高版本。在較舊的 TypeScript 版本中,模板字面量類型可能不被支持。

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020"],
    "typescriptVersion": ">=4.1.0"
  }
}

9.2 聯(lián)合類型在模板字面量中的行為

當(dāng)模板字面量類型中的某部分是一個聯(lián)合類型時,結(jié)果會是所有可能組合的聯(lián)合:

type A = 'x' | 'y';
type B = '1' | '2';
type C = `${A}${B}`;
// "x1" | "x2" | "y1" | "y2"

9.3 大小寫轉(zhuǎn)換工具類型

TypeScript 的內(nèi)置大小寫轉(zhuǎn)換工具類型只對 ASCII 字符有效。如果你需要處理其他語言的字符,可能需要自定義實現(xiàn):

type UppercaseFirst<T extends string> = 
  T extends `${infer First}${infer Rest}`
    ? `${Uppercase<First>}${Rest}`
    : T;
type LowercaseFirst<T extends string> = 
  T extends `${infer First}${infer Rest}`
    ? `${Lowercase<First>}${Rest}`
    : T;

十、總結(jié)

模板字面量類型是 TypeScript 類型系統(tǒng)中最強大的特性之一。它不僅可以讓你的類型定義更加精確和類型安全,還能在編譯時捕獲許多潛在的類型錯誤。通過掌握模板字面量類型,你可以寫出更加健壯、可維護的 TypeScript 代碼。

到此這篇關(guān)于TypeScript模板字面量類型高級用法的文章就介紹到這了,更多相關(guān)TS模板字面量類型高級用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript cookie原理及使用實例

    JavaScript cookie原理及使用實例

    這篇文章主要介紹了JavaScript cookie原理及使用實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • JavaScript實現(xiàn)滾動加載更多

    JavaScript實現(xiàn)滾動加載更多

    這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)滾動加載更多,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • JavaScript中iframe實現(xiàn)局部刷新的幾種方法匯總

    JavaScript中iframe實現(xiàn)局部刷新的幾種方法匯總

    Iframe是一種嵌入網(wǎng)頁的框架形式,Web頁面可以通過更改嵌入的部分,達到部分內(nèi)容刷新,通過本文和大家一起學(xué)習(xí)iframe實現(xiàn)局部刷新的幾種方法匯總,對iframe局部刷新相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • JS實現(xiàn)短信驗證碼一鍵登錄功能

    JS實現(xiàn)短信驗證碼一鍵登錄功能

    短信驗證碼一鍵登錄是一種方便快捷的登錄方式,本文介紹了其原理并給出了一個簡單的JavaScript示例,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • layer.open回調(diào)獲取彈出層參數(shù)的實現(xiàn)方法

    layer.open回調(diào)獲取彈出層參數(shù)的實現(xiàn)方法

    今天小編就為大家分享一篇layer.open回調(diào)獲取彈出層參數(shù)的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • ES6(ECMAScript 6)新特性之模板字符串用法分析

    ES6(ECMAScript 6)新特性之模板字符串用法分析

    這篇文章主要介紹了ES6(ECMAScript 6)新特性之模板字符串用法,簡單介紹了ES6模板字符串的概念、功能并結(jié)合實例形式分析了ES6模板字符串的用法,需要的朋友可以參考下
    2017-04-04
  • JavaScript實現(xiàn)為指定對象添加多個事件處理程序的方法

    JavaScript實現(xiàn)為指定對象添加多個事件處理程序的方法

    這篇文章主要介紹了JavaScript實現(xiàn)為指定對象添加多個事件處理程序的方法,可實現(xiàn)讓指定對象處理多個事件的功能,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • IE及IE6瀏覽器中判斷JS文件加載成功失敗的方法

    IE及IE6瀏覽器中判斷JS文件加載成功失敗的方法

    這篇文章主要介紹了IE及IE6瀏覽器中判斷JS文件加載成功失敗的方法,本文使用vbscript來解決這個問題,需要的朋友可以參考下
    2015-02-02
  • 原生Javascript封裝的一個AJAX函數(shù)分享

    原生Javascript封裝的一個AJAX函數(shù)分享

    這篇文章主要介紹了原生Javascript封裝的一個AJAX函數(shù)分享,本文是實際項目中提取出來的,簡單易用,需要的朋友可以參考下
    2014-10-10
  • JS實現(xiàn)長圖上下滾動效果

    JS實現(xiàn)長圖上下滾動效果

    這篇文章主要為大家詳細(xì)介紹了JS實現(xiàn)長圖上下滾動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03

最新評論

阜南县| 安新县| 资兴市| 青神县| 丰县| 云林县| 诸暨市| 永州市| 永善县| 乐都县| 平果县| 阿坝县| 驻马店市| 若羌县| 原平市| 临洮县| 昌都县| 古丈县| 任丘市| 双流县| 建宁县| 盐边县| 满城县| 武定县| 仙桃市| 宁阳县| 南安市| 眉山市| 长海县| 屏东市| 白城市| 郓城县| 江西省| 开鲁县| 崇仁县| 昭通市| 绍兴县| 太湖县| 襄城县| 肥城市| 济源市|