动态

详情 返回 返回

「譯」如何寫出更好的Typescript代碼 - 动态 详情

鏈接:https://medium.com/@technicadil_001/how-to-write-better-types...

作者:Debabrata Dash

原標題:How to write better Typescript codes?

在本文中,我們將討論大約 15 個編寫更好的 Typescript 代碼的技巧。

img

譯者:本文討論了 15 個實用技巧,以幫助開發者編寫更好的 TypeScript 代碼。這些技巧包括可選鏈接、映射類型、實用類型等,旨在提高代碼的安全性、可讀性和功能性。通過這些技巧,開發者可以更有效地管理數據類型,從而構建更穩健的應用程序。

1 可選鏈 (?.):

通過可選的鏈接,您可以安全地訪問嵌套的屬性或方法,而無需擔心 null 值或未定義的值。如果任何中間屬性為 null 或未定義,它就會短路評估。

const user = {
  name: 'Piotr',
  address: {
    city: 'Warsaw',
    postalCode: '00-240'
  }
};


const postalCode = user.address?.postalCode;
console.log(postalCode); // 00-240

const invalidCode = user.address?.postalCode?.toLowerCase();
console.log(invalidCode); // Output: undefined

2 使用映射類型進行轉換

映射類型允許您通過轉換現有類型的屬性來創建新類型。

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};
type Partial<T> = {
  [P in keyof T]?: T[P];
};

3 善用實用程序類型

TypeScript 提供了多種實用程序類型來幫助進行常見的類型轉換。

i)Partial<T>:使所有屬性成為可選屬性。
ii) Required<T>: 使所有屬性成為必需屬性。
iii) Readonly<T>: 將所有屬性設置為只讀。
iv) Record<K, T>: 使用類型為 T 的鍵 K 創建一個類型。

type Person = {
  name: string;
  age: number;
};
type PartialPerson = Partial<Person>;
type ReadonlyPerson = Readonly<Person>;

4 類型防護

使用 Type Guards 縮小條件塊中的類型範圍

function isString(value: unknown): value is string {
  return typeof value === 'string';
}

5 模板文字類型

Tese 允許您通過組合字符串文字來創建新的字符串類型。

type EventName = 'click' | 'hover';
type EventHandlerName = `${EventName}Handler`; // 'clickHandler' | 'hoverHandler'

6 使用索引訪問類型

使用索引訪問類型來提取屬性的類型。

type Person = { name: string; age: number };
type NameType = Person['name']; // string

7 將映射類型中的鍵重新映射

創建新類型時,轉換鍵。

type PrefixKeys<T, P extends string> = {
  [K in keyof T as `${P}${K & string}`]: T[K]
};
type PrefixedPerson = PrefixKeys<{ name: string; age: number }, 'prefix_'>;
// { prefix_name: string; prefix_age: number }

8 Discriminated 聯合類型

這些可以幫助您創建不同類型的類型安全聯合。

type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; side: number };

function getArea(shape: Shape) {
  switch (shape.kind) {
    case 'circle': return Math.PI * shape.radius ** 2;
    case 'square': return shape.side ** 2;
  }
}

9 泛型中的類型推斷

利用 ‘infer’ 提取並使用條件類型中的類型。

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
type Fn = () => number;
type Result = ReturnType<Fn>; // number

10 模塊增強

使用新功能擴展現有模塊。

// augmentations.ts
import 'express';
declare module 'express' {
  interface Request {
    user?: { id: string; role: string };
  }
}

11 聲明合併的interface

合併 interface 以擴展類型,對於第三方庫尤其有用。

interface Window {
  myCustomProperty: string;
}
window.myCustomProperty = 'Hello!';

12 函數重載

提供多個函數簽名以更好地進行類型檢查。

function createDate(timestamp: number): Date;
function createDate(year: number, month: number, day: number): Date;
function createDate(x: number, y?: number, z?: number): Date {
  return y !== undefined && z !== undefined ? new Date(x, y, z) : new Date(x);
}

13 Branded 類型

使用 Branded 類型來創建名義類型。

type UserId = string & { _brand: 'UserId' };
function createUserId(id: string): UserId {
  return id as UserId;
}

14 具有條件類型的模板文字類型

將模板文字類型與條件類型相結合以進行高級字符串操作。

type ExtractRouteParams<T extends string> = T extends `/${infer Param}/${infer Rest}`
  ? { param: Param } & ExtractRouteParams<`/${Rest}`>
  : {};

type Params = ExtractRouteParams<'/user/:id/posts/:postId'>;
// { param: 'user' } & { param: 'posts' }

15 可變參數元組類型

Typescript 4+ 支持可變元組類型,允許元組捕獲數組的其餘部分。

type Push<T extends any[], V> = [...T, V];
type Result = Push<[1, 2, 3], 4>; // [1, 2, 3, 4]
user avatar tianmiaogongzuoshi_5ca47d59bef41 头像 dingtongya 头像 cyzf 头像 Leesz 头像 alibabawenyujishu 头像 linlinma 头像 freeman_tian 头像 front_yue 头像 littlelyon 头像 dawanzi_6278b06ec111c 头像 razyliang 头像 hard_heart_603dd717240e2 头像
点赞 245 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.