十個高級開發(fā)者需要知道的TypeScript 技巧
TypeScript 已迅速成為像我這樣的開發(fā)人員的首選語言,他們希望通過添加類型安全、更好的工具和改進(jìn)的可維護(hù)性來改進(jìn) JavaScript 代碼庫。
隨著語言的發(fā)展和成熟,TypeScript 沿途獲得了一些隱藏的功能。 在本文中,我們將深入探討 10 個鮮為人知的技巧,它們將幫助您釋放 TypeScript 的全部潛力。
1. 使用 keyof 和映射類型動態(tài)構(gòu)建類型
keyof 關(guān)鍵字提供了一種基于現(xiàn)有類型的鍵動態(tài)構(gòu)建類型的強(qiáng)大工具。
“keyof 運(yùn)算符采用對象類型并生成其鍵的字符串或數(shù)字文字聯(lián)合?!?/em>
— TypeScript 文檔
結(jié)合映射類型,您可以從現(xiàn)有類型生成新類型,同時保留原始結(jié)構(gòu)。
type Point = { x: number; y: number };
type NullablePoint = {
[K in keyof Point]: Point[K] | null;
};
在這里,NullablePoint 成為一種新類型,具有與 Point 相同的鍵,但具有可為空的值。
2. 靈活類型的條件類型
條件類型允許創(chuàng)建依賴于其他類型的復(fù)雜類型。 這可以導(dǎo)致更靈活和可重用的類型定義。
type Flatten<T> = T extends Array<infer U> ? U : T;
type FlattenedNumbers = Flatten<number[]>; // number
在此示例中,F(xiàn)latten 類型檢查提供的類型 T 是否為數(shù)組,如果是,則提取內(nèi)部類型 U。
3. 類型柯里化的部分應(yīng)用類型
TypeScript 對高階類型的支持允許您創(chuàng)建部分應(yīng)用的類型。 這種稱為類型套用的技術(shù)可實(shí)現(xiàn)強(qiáng)大的組合模式。
type Curried<T, U> = (arg: U) => T & U;
function merge<T, U>(fn: Curried<T, U>): T & U {
return fn({} as U);
}
type UserDetails = { firstName: string; lastName: string };
type UserSettings = { theme: string; language: string };
const result = merge<UserDetails, UserSettings>(() => ({
firstName: 'John',
lastName: 'Doe',
theme: 'dark',
language: 'en',
}));
console.log(result);
/** {
"firstName": "John",
"lastName": "Doe",
"theme": "dark",
"language": "en"
} */
在此示例中,我們有兩種不同類型的對象,UserDetails 和 UserSettings。 通過使用 merge 函數(shù),我們可以將這兩種類型組合成一個包含兩種類型屬性的對象。 當(dāng)您想要創(chuàng)建一個新對象來組合來自多個來源的屬性,同時仍保持 TypeScript 類型完整時,這會很有用。
當(dāng)然,在 TypeScript 中還有其他方法可以實(shí)現(xiàn)這一點(diǎn),例如,使用類型交集和直接擴(kuò)展語法。 此示例的主要目的是演示類型柯里化的概念,當(dāng)在正確的上下文中應(yīng)用時,它可以成為一種強(qiáng)大的技術(shù)。
4. 編譯時類型檢查的類型保護(hù)
當(dāng)您需要執(zhí)行編譯時類型檢查時,類型保護(hù)很有用。 它們允許 TypeScript 縮小特定代碼塊中值的類型。
function isString(value: any): value is string {
return typeof value === "string";
}
function concat(a: unknown, b: unknown) {
if (isString(a) && isString(b)) {
return a.concat(b);
}
}
在 concat 函數(shù)中,TypeScript 知道 a 和 b 是字符串,因?yàn)轭愋捅Wo(hù)是 isString。 這也可以改進(jìn) VS Code Intellisense 的提示,因?yàn)榫幾g器將能夠約束任何類型。
5. 帶返回類型的高級類型推斷
Return Type 實(shí)用程序類型可以推斷函數(shù)的返回類型,從而更容易使用高階函數(shù)及其類型。
type MyFunction = (x: number, y: number) => { result: number };
type MyFunctionReturnType = ReturnType<MyFunction>; // { result: number }
在這里,MyFunctionReturnType 成為 MyFunction 的推斷返回類型。
6. 遞歸類型的類型級編程
TypeScript 支持遞歸類型,允許您創(chuàng)建復(fù)雜的類型級計(jì)算和轉(zhuǎn)換。
type TupleToUnion<T extends any[]> = T[number];
type MyTuple = [string, number, boolean];
type MyUnion = TupleToUnion<MyTuple>; // string | number | boolean
在此示例中,TupleToUnion 將元組類型轉(zhuǎn)換為聯(lián)合類型,這在處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)時非常有用。
就個人而言,我更喜歡聯(lián)合類型而不是枚舉,以至于我會將我看到的任何枚舉重構(gòu)為聯(lián)合類型。 智能感知更好!
7. 不可變類型只讀
TypeScript 提供了一個內(nèi)置的 Readonly 實(shí)用程序類型,它使對象的所有屬性都成為只讀的。 當(dāng)您想在代碼庫中強(qiáng)制執(zhí)行不變性時,這很有用。
type User = { name: string; age: number };
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = { name: "Alice", age: 30 };
user.age = 31;
// Error: Cannot assign to 'age' because it is a read-only property
通過使用 Readonly 實(shí)用程序,我們確保用戶對象不會發(fā)生變化。
8. 類型斷言以獲得更多控制
當(dāng)您對值的類型的了解比 TypeScript 的類型推斷所能推斷的更多時,類型斷言很有用。 它們允許您為值指定更精確的類型,而無需執(zhí)行任何運(yùn)行時檢查。
const unknownValue: unknown = "hello world";
const stringValue: string = unknownValue as string;
在此示例中,我們斷言 unknownValue 確實(shí)是一個字符串,TypeScript 將信任此斷言。
9. 更安全常量的唯一符號
TypeScript 獨(dú)特的符號類型可以創(chuàng)建獨(dú)特的非字符串值,非常適合更安全的常量定義和避免名稱沖突。
const MyConstant = Symbol("MyConstant") as unique symbol;
type MyType = {
[MyConstant]: string;
};
const obj: MyType = { [MyConstant]: "hello world" };
console.log(obj[MyConstant]); // "hello world"
在這里,MyConstant 是一個獨(dú)特的符號,確保沒有其他屬性可以與它沖突。
10.代碼組織的合并類型聲明
TypeScript 允許合并類型聲明,這在跨多個文件拆分類型定義或從外部庫擴(kuò)展類型時非常有用。
// file1.ts
interface Point {
x: number;
y: number;
}
// file2.ts
interface Point {
z: number;
}
// Merged Point type: { x: number; y: number; z: number }
通過在 file1.ts 和 file2.ts 中聲明 Point,TypeScript 會將兩個聲明合并為一個類型。 我認(rèn)為這種行為只發(fā)生在 interface 關(guān)鍵字上,而不是 type 關(guān)鍵字,所以我更喜歡 type。
這 10 個 TypeScript 提示和技巧應(yīng)該可以幫助您提升 TypeScript 技能并編寫更強(qiáng)大、靈活和可維護(hù)的代碼。
不要害怕探索 TypeScript 的高級功能,并在您的項(xiàng)目中利用它們來實(shí)現(xiàn)更干凈、更安全的代碼。