自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

好好好,能讓 DeepSeek 思考 266 秒,還得是你 TypeScript 類型體操 | 類型系統(tǒng)循環(huán)依賴

開(kāi)發(fā) 前端 人工智能
以下是關(guān)于這個(gè) TypeScript 類型問(wèn)題的原理剖析,通過(guò)循序漸進(jìn)的分析來(lái)理解背后的類型系統(tǒng)邏輯。

大晚上突發(fā)奇想,要鍛煉身體。

做個(gè)什么運(yùn)動(dòng)呢?要選個(gè)室內(nèi)的、適合我這個(gè)小小出租屋的,最好還是有點(diǎn)樂(lè)趣和挑戰(zhàn)性的。

那就做個(gè)體操吧!對(duì), TypeScript 類型體操!

咱第一次做這個(gè)體操,于是想了個(gè)“簡(jiǎn)單點(diǎn)”的場(chǎng)景,練練手。

我的需求是這樣的:

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

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

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

這樣,用就可以自己定義加密算法和配置了。比如用戶可以實(shí)現(xiàn)一個(gè) AESGCMEncryption 加密算法,和一個(gè) AESGCMEncryptionConfigFromEnv 配置類。

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

export class AESGCMEncryption implements IEncryptionAlgorithm<IAESGCMEncryptionConfig> { }

export class AESGCMEncryptionConfigFromEnv implements IAESGCMEncryptionConfig { }

但是問(wèn)題來(lái)了,對(duì)于 AESGCMEncryption 加密算法,它的配置類必須是 IAESGCMEncryptionConfig ,否則就無(wú)法正確獲取 password 、 salt 、 iv 這三個(gè)屬性。

然而,在目前的類型聲明中,這一點(diǎn)是無(wú)法做到的:

// encryptionService 類型是正確的,沒(méi)問(wèn)題
let encryptionService: EncryptionService<AESGCMEncryption, AESGCMEncryptionConfigFromEnv>;

// encryptionService2 也是正確的,類型系統(tǒng)沒(méi)有報(bào)錯(cuò)
// 但是應(yīng)該報(bào)錯(cuò),因?yàn)?IEncryptionAlgorithmConfig 沒(méi)有 password 、 salt 、 iv 這三個(gè)屬性
// IEncryptionAlgorithmConfig 并不適合 AESGCMEncryption 加密算法
let encryptionService2: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>;

那么我當(dāng)然是求助我的體操教練 deepseek-r1 。

教練說(shuō):這個(gè)問(wèn)題好解決,但是你先去洗個(gè)澡再回來(lái)。

我說(shuō):老師我看您面色如鐵,怎么好像有點(diǎn)猶豫?

教練說(shuō):幾百年沒(méi)見(jiàn)過(guò)玩 TypeScript 類型體操的了!你也就是走運(yùn),今天我有心情理你!

第一次問(wèn)答 DeepSeek 給出的解決方案:

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

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

很遺憾,并沒(méi)有解決問(wèn)題。

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

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

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

這次終于解決了問(wèn)題。

最后,教練授之以漁。

DeepSeek-R1

以下是關(guān)于這個(gè) TypeScript 類型問(wèn)題的原理剖析,通過(guò)循序漸進(jìn)的分析來(lái)理解背后的類型系統(tǒng)邏輯:

第一章:基礎(chǔ)場(chǎng)景分析

1.原始問(wèn)題

我們有一個(gè)加密服務(wù)類 EncryptionService,它需要兩個(gè)泛型參數(shù):

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

期望實(shí)現(xiàn):

  • 當(dāng) TAlgorithm 是 AESGCMEncryption 時(shí)
  • TConfig 必須 是 IAESGCMEncryptionConfig
  • 不能 使用其他類型(如基礎(chǔ)接口 IEncryptionAlgorithmConfig)

2.直觀嘗試

用戶最初嘗試這樣定義:

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

期望:

  • TConfig 自動(dòng)從 TAlgorithm 中提取配置類型。
  • 實(shí)現(xiàn)類型關(guān)聯(lián)約束。

但發(fā)現(xiàn)以下用法沒(méi)有報(bào)錯(cuò):

let service: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>; // 不報(bào)錯(cuò) ?

第二章:類型系統(tǒng)的局限

1.循環(huán)依賴問(wèn)題

當(dāng)這樣定義時(shí):

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

實(shí)際上創(chuàng)建了循環(huán)依賴:

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

TypeScript 無(wú)法解析這種循環(huán)依賴,會(huì)觸發(fā)錯(cuò)誤:

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

2.類型推導(dǎo)的妥協(xié)

當(dāng)使用:

TConfig extends IEncryptionAlgorithmConfig = ConfigType<TAlgorithm>

實(shí)際上:

  • TConfig 的約束是寬泛的 IEncryptionAlgorithmConfig
  • 默認(rèn)值使用 ConfigType<TAlgorithm> 推導(dǎo)

結(jié)果:

  • 顯式指定 TConfig 時(shí)(如 IEncryptionAlgorithmConfig)。
  • 只要滿足 IEncryptionAlgorithmConfig 的約束就能通過(guò)檢查。
  • 失去了與 TAlgorithm 的嚴(yán)格關(guān)聯(lián)。

第三章:突破循環(huán)依賴

1.關(guān)鍵思路轉(zhuǎn)變

我們需要:

  • 解除 TAlgorithm 和 TConfig 的直接循環(huán)。
  • 通過(guò)第三方類型工具建立間接關(guān)聯(lián)。

2.引入類型提取工具

定義條件類型:

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

這個(gè)類型的作用:

  • 如果 T 是實(shí)現(xiàn)了 IEncryptionAlgorithm<C> 的類。
  • 則提取出配置類型 C。

3.重構(gòu)泛型參數(shù)

class EncryptionService<
  TAlgorithm extends IEncryptionAlgorithm<any>, // 臨時(shí)放寬約束
  TConfig extends EncryptionConfigType<TAlgorithm> // 關(guān)鍵約束
> {}

4.分步解析

當(dāng)用戶這樣使用時(shí):

type Test1 = EncryptionConfigType<AESGCMEncryption>;
// 等價(jià)于 IAESGCMEncryptionConfig

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

此時(shí)泛型參數(shù)的邏輯:

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

第四章:類型推導(dǎo)過(guò)程

1.合法用法分析

let service: EncryptionService<AESGCMEncryption>;

推導(dǎo)過(guò)程:

  • TAlgorithm = AESGCMEncryption
  • TConfig = EncryptionConfigType<AESGCMEncryption> → IAESGCMEncryptionConfig
  • 驗(yàn)證 AESGCMEncryption 是否滿足 IEncryptionAlgorithm<any> → 滿足

2.非法用法分析

let service: EncryptionService<AESGCMEncryption, IEncryptionAlgorithmConfig>;

推導(dǎo)過(guò)程:

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

第五章:關(guān)鍵差異對(duì)比

1.原始方案的問(wèn)題

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

建立了:

TAlgo → TConfig → TAlgo → TConfig...

形成閉環(huán),類型系統(tǒng)無(wú)法展開(kāi)推導(dǎo)

2.最終方案的優(yōu)勢(shì)

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

建立:

TAlgo → (通過(guò) EncryptionConfigType) → TConfig

形成單向推導(dǎo)鏈,打破循環(huán)

第六章:技術(shù)總結(jié)

1.核心知識(shí)點(diǎn)

條件類型(Conditional Types):

T extends U ? X : Y

允許根據(jù)類型關(guān)系進(jìn)行類型推導(dǎo)

類型推斷(infer):

T extends IEncryptionAlgorithm<infer C> ? C : never

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

泛型約束解耦:通過(guò)中間類型工具打破循環(huán)依賴

2. 設(shè)計(jì)原則

關(guān)注點(diǎn)分離:

  • 算法類的定義與其配置類型解耦
  • 通過(guò)類型工具建立關(guān)聯(lián)

推導(dǎo)優(yōu)于顯式聲明:

  • 優(yōu)先讓類型系統(tǒng)自動(dòng)推導(dǎo)
  • 顯式聲明時(shí)進(jìn)行嚴(yán)格檢查

第七章:擴(kuò)展思考

1.如果增加新加密算法

class RSAEncryption implements IEncryptionAlgorithm<IRSAConfig> {}

類型系統(tǒng)會(huì)自動(dòng)保證:

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

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

在:

TAlgorithm extends IEncryptionAlgorithm<any>

中:

  • any 僅用于臨時(shí)繞過(guò)類型檢查。
  • 實(shí)際約束由 TConfig extends EncryptionConfigType<TAlgorithm> 保證。
  • 最終使用時(shí)類型系統(tǒng)仍會(huì)驗(yàn)證實(shí)際類型。

通過(guò)這種層層遞進(jìn)的分析,我們可以理解 TypeScript 類型系統(tǒng)在處理復(fù)雜泛型關(guān)系時(shí)的行為模式,以及如何通過(guò)合理的類型工具設(shè)計(jì)來(lái)實(shí)現(xiàn)嚴(yán)格的類型關(guān)聯(lián)約束。

責(zé)任編輯:姜華 來(lái)源: Piper蛋窩
相關(guān)推薦

2022-09-20 14:43:55

TypeScript類型體操

2025-04-10 05:00:00

JavaScriptReactWeb

2021-12-10 08:21:15

TypeScript高級(jí)類型類型體操

2022-06-19 22:54:08

TypeScript泛型工具

2022-06-14 09:04:55

前端npm

2022-03-09 20:18:49

TypeScript類型函數(shù)

2022-01-05 12:03:48

MySQL索引數(shù)據(jù)

2021-06-09 07:55:19

Typescript類型檢查

2022-02-09 08:11:50

架構(gòu)

2024-04-29 08:52:49

2017-08-31 09:19:50

硬盤服務(wù)器云存儲(chǔ)

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-02-03 08:52:52

Mysql索引數(shù)據(jù)庫(kù)

2021-11-29 22:51:14

GoPHPRust

2020-12-18 11:35:22

TypeScript語(yǔ)言Java

2022-04-10 19:26:07

TypeScript類型語(yǔ)法

2015-06-10 09:14:30

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)