成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

好好好,能讓 DeepSeek 思考 266 秒,還得是你 TypeScript 類型體操 | 類型系統循環依賴

開發 前端 人工智能
以下是關于這個 TypeScript 類型問題的原理剖析,通過循序漸進的分析來理解背后的類型系統邏輯。

大晚上突發奇想,要鍛煉身體。

做個什么運動呢?要選個室內的、適合我這個小小出租屋的,最好還是有點樂趣和挑戰性的。

那就做個體操吧!對, TypeScript 類型體操!

咱第一次做這個體操,于是想了個“簡單點”的場景,練練手。

我的需求是這樣的:

  • 有兩個接口, IEncryptionAlgorithm 和 IEncryptionAlgorithmConfig ,分別是加密算法的接口和配置接口。
  • 還有一個 EncryptionService<T, U> , T 是加密算法的接口, U 是配置接口。
// 加密算法配置接口
export interface IEncryptionAlgorithmConfig { }

// 加密算法接口
export interface IEncryptionAlgorithm<T extends IEncryptionAlgorithmConfig> { }

// 加密服務
export class EncryptionService<
    TAlgorithm extends IEncryptionAlgorithm<TConfig>,
    TConfig extends IEncryptionAlgorithmConfig
> { }

這樣,用就可以自己定義加密算法和配置了。比如用戶可以實現一個 AESGCMEncryption 加密算法,和一個 AESGCMEncryptionConfigFromEnv 配置類。

export interface IAESGCMEncryptionConfig extends IEncryptionAlgorithmConfig {
    password: string;
    salt: Uint8Array;
    iv: Uint8Array;
}

export class AESGCMEncryption implements IEncryptionAlgorithm<IAESGCMEncryptionConfig> { }

export class AESGCMEncryptionConfigFromEnv implements IAESGCMEncryptionConfig { }

但是問題來了,對于 AESGCMEncryption 加密算法,它的配置類必須是 IAESGCMEncryptionConfig ,否則就無法正確獲取 password 、 salt 、 iv 這三個屬性。

然而,在目前的類型聲明中,這一點是無法做到的:

// encryptionService 類型是正確的,沒問題
let encryptionService: EncryptionService<AESGCMEncryption, AESGCMEncryptionConfigFromEnv>;

// encryptionService2 也是正確的,類型系統沒有報錯
// 但是應該報錯,因為 IEncryptionAlgorithmConfig 沒有 password 、 salt 、 iv 這三個屬性
// IEncryptionAlgorithmConfig 并不適合 AESGCMEncryption 加密算法
let encryptionService2: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>;

那么我當然是求助我的體操教練 deepseek-r1 。

教練說:這個問題好解決,但是你先去洗個澡再回來。

我說:老師我看您面色如鐵,怎么好像有點猶豫?

教練說:幾百年沒見過玩 TypeScript 類型體操的了!你也就是走運,今天我有心情理你!

第一次問答 DeepSeek 給出的解決方案:

// 新增類型工具:從算法類中提取配置類型
export type ConfigType<T> = T extends IEncryptionAlgorithm<infer C> ? C : never;

export class EncryptionService<
    TAlgorithm extends IEncryptionAlgorithm<TConfig>,
    TConfig extends IEncryptionAlgorithmConfig = ConfigType<TAlgorithm>
> { }

很遺憾,并沒有解決問題。

再次向教練描述情況后,教練終于給出了正確方案:

export type EncryptionConfigType<T> = T extends IEncryptionAlgorithm<infer C> ? C : never;

export class EncryptionService<
    TAlgorithm extends IEncryptionAlgorithm<any>,
    TConfig extends EncryptionConfigType<TAlgorithm> = EncryptionConfigType<TAlgorithm>
> { }

這次終于解決了問題。

最后,教練授之以漁。

DeepSeek-R1

以下是關于這個 TypeScript 類型問題的原理剖析,通過循序漸進的分析來理解背后的類型系統邏輯:

第一章:基礎場景分析

1.原始問題

我們有一個加密服務類 EncryptionService,它需要兩個泛型參數:

class EncryptionService<
  TAlgorithm extends IEncryptionAlgorithm<TConfig>,
  TConfig extends IEncryptionAlgorithmConfig
> {}

期望實現:

  • 當 TAlgorithm 是 AESGCMEncryption 時
  • TConfig 必須 是 IAESGCMEncryptionConfig
  • 不能 使用其他類型(如基礎接口 IEncryptionAlgorithmConfig)

2.直觀嘗試

用戶最初嘗試這樣定義:

class EncryptionService<
  TAlgorithm extends IEncryptionAlgorithm<TConfig>,
  TConfig extends IEncryptionAlgorithmConfig = ConfigType<TAlgorithm>
> {}

期望:

  • TConfig 自動從 TAlgorithm 中提取配置類型。
  • 實現類型關聯約束。

但發現以下用法沒有報錯:

let service: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>; // 不報錯 ?

第二章:類型系統的局限

1.循環依賴問題

當這樣定義時:

TAlgorithm extends IEncryptionAlgorithm<TConfig>
TConfig extends ConfigType<TAlgorithm>

實際上創建了循環依賴:

  • 要確定 TAlgorithm 需要先知道 TConfig。
  • 要確定 TConfig 又需要先知道 TAlgorithm。

TypeScript 無法解析這種循環依賴,會觸發錯誤:

Type parameter 'TConfig' has a circular constraint.ts(2313)

2.類型推導的妥協

當使用:

TConfig extends IEncryptionAlgorithmConfig = ConfigType<TAlgorithm>

實際上:

  • TConfig 的約束是寬泛的 IEncryptionAlgorithmConfig
  • 默認值使用 ConfigType<TAlgorithm> 推導

結果:

  • 顯式指定 TConfig 時(如 IEncryptionAlgorithmConfig)。
  • 只要滿足 IEncryptionAlgorithmConfig 的約束就能通過檢查。
  • 失去了與 TAlgorithm 的嚴格關聯。

第三章:突破循環依賴

1.關鍵思路轉變

我們需要:

  • 解除 TAlgorithm 和 TConfig 的直接循環。
  • 通過第三方類型工具建立間接關聯。

2.引入類型提取工具

定義條件類型:

type EncryptionConfigType<T> = 
  T extends IEncryptionAlgorithm<infer C> ? C : never;

這個類型的作用:

  • 如果 T 是實現了 IEncryptionAlgorithm<C> 的類。
  • 則提取出配置類型 C。

3.重構泛型參數

class EncryptionService<
  TAlgorithm extends IEncryptionAlgorithm<any>, // 臨時放寬約束
  TConfig extends EncryptionConfigType<TAlgorithm> // 關鍵約束
> {}

4.分步解析

當用戶這樣使用時:

type Test1 = EncryptionConfigType<AESGCMEncryption>;
// 等價于 IAESGCMEncryptionConfig

type Test2 = EncryptionConfigType<string>; // 得到 never

此時泛型參數的邏輯:

  • 先確定 TAlgorithm 是某個加密算法類
  • 通過 EncryptionConfigType<TAlgorithm> 提取其配置類型
  • 要求 TConfig 必須匹配該配置類型

第四章:類型推導過程

1.合法用法分析

let service: EncryptionService<AESGCMEncryption>;

推導過程:

  • TAlgorithm = AESGCMEncryption
  • TConfig = EncryptionConfigType<AESGCMEncryption> → IAESGCMEncryptionConfig
  • 驗證 AESGCMEncryption 是否滿足 IEncryptionAlgorithm<any> → 滿足

2.非法用法分析

let service: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>;

推導過程:

  • TAlgorithm = AESGCMEncryption
  • TConfig = IEncryptionAlgorithmConfig
  • 檢查 IEncryptionAlgorithmConfig 是否滿足 EncryptionConfigType<AESGCMEncryption> → 等價于檢查 IEncryptionAlgorithmConfig extends IAESGCMEncryptionConfig → 失敗

第五章:關鍵差異對比

1.原始方案的問題

class Service<TAlgo extends IEncryptionAlgorithm<TConfig>, TConfig...>

建立了:

TAlgo → TConfig → TAlgo → TConfig...

形成閉環,類型系統無法展開推導

2.最終方案的優勢

class Service<TAlgo extends IEncryptionAlgorithm<any>, TConfig...>

建立:

TAlgo → (通過 EncryptionConfigType) → TConfig

形成單向推導鏈,打破循環

第六章:技術總結

1.核心知識點

條件類型(Conditional Types):

T extends U ? X : Y

允許根據類型關系進行類型推導

類型推斷(infer):

T extends IEncryptionAlgorithm<infer C> ? C : never

從泛型類型中提取嵌套類型

泛型約束解耦:通過中間類型工具打破循環依賴

2. 設計原則

關注點分離:

  • 算法類的定義與其配置類型解耦
  • 通過類型工具建立關聯

推導優于顯式聲明:

  • 優先讓類型系統自動推導
  • 顯式聲明時進行嚴格檢查

第七章:擴展思考

1.如果增加新加密算法

class RSAEncryption implements IEncryptionAlgorithm<IRSAConfig> {}

類型系統會自動保證:

let service: EncryptionService<RSAEncryption>; // TConfig = IRSAConfig
let service: EncryptionService<RSAEncryption, IAESGCMEncryptionConfig>; // 錯誤 ?

2.為什么使用 any 是安全的

在:

TAlgorithm extends IEncryptionAlgorithm<any>

中:

  • any 僅用于臨時繞過類型檢查。
  • 實際約束由 TConfig extends EncryptionConfigType<TAlgorithm> 保證。
  • 最終使用時類型系統仍會驗證實際類型。

通過這種層層遞進的分析,我們可以理解 TypeScript 類型系統在處理復雜泛型關系時的行為模式,以及如何通過合理的類型工具設計來實現嚴格的類型關聯約束。

責任編輯:姜華 來源: Piper蛋窩
相關推薦

2022-09-20 14:43:55

TypeScript類型體操

2025-04-10 05:00:00

JavaScriptReactWeb

2022-06-19 22:54:08

TypeScript泛型工具

2021-12-10 08:21:15

TypeScript高級類型類型體操

2022-06-14 09:04:55

前端npm

2022-01-05 12:03:48

MySQL索引數據

2022-03-09 20:18:49

TypeScript類型函數

2021-06-09 07:55:19

Typescript類型檢查

2024-04-29 08:52:49

2017-08-31 09:19:50

硬盤服務器云存儲

2022-02-09 08:11:50

架構

2020-09-15 08:35:57

TypeScript JavaScript類型

2022-08-10 09:03:35

TypeScript前端

2024-02-19 10:24:32

Chainable工具類型類型體操

2024-03-04 06:40:49

工具類型TypeScripDeepPick

2021-11-29 22:51:14

GoPHPRust

2021-02-03 08:52:52

Mysql索引數據庫

2015-06-10 09:14:30

2022-04-10 19:26:07

TypeScript類型語法

2020-12-18 11:35:22

TypeScript語言Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av在线视 | 亚洲精品9999久久久久 | 欧美又大粗又爽又黄大片视频 | 国产精品一区免费 | 午夜色婷婷 | 欧美小视频在线观看 | 日韩视频一区二区在线 | 日韩精品一区二区三区在线播放 | 欧美福利在线 | 国产欧美日韩在线 | 午夜久久久久 | 久久久久久成人 | 色资源站| 日韩福利电影 | 亚洲91精品| 久久久国产精品 | 亚洲欧洲成人av每日更新 | 国产亚洲精品精品国产亚洲综合 | 美女天天操 | 亚洲精品自在在线观看 | 亚洲国产精品久久人人爱 | www国产亚洲精品久久网站 | 91高清视频在线观看 | 奇米久久 | 在线免费91 | 少妇精品亚洲一区二区成人 | 老司机成人在线 | 国产真实精品久久二三区 | 亚洲欧美中文字幕 | 久久性色 | 久久精品视频亚洲 | 精品国产鲁一鲁一区二区张丽 | 国产日韩精品视频 | 青青久久av北条麻妃海外网 | 久久久久久久网 | 91在线视频一区 | 国产精品国产三级国产aⅴ浪潮 | 日本五月婷婷 | 99热精品在线 | 狠狠干天天干 | 成人看片在线观看 |