欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

TypeScript真的很麻煩導致不想使用嗎?


2024年3月21日 8:28 本文熱度 752

前言

最近,我們部門在開發一個組件庫時,我注意到一些團隊成員對使用TypeScript表示出了抵觸情緒,他們常常抱怨說:“TypeScript太麻煩了,我們不想用!”起初,我對此感到困惑:TypeScript真的有那么麻煩嗎?然而,當我抽時間審查隊伍的代碼時,我終于發現了問題所在。在這篇文章中,我想和大家分享我的一些發現和解決方案。

一、類型復用不足

在代碼審查過程中,我發現了大量的重復類型定義,這顯著降低了代碼的復用性。

進一步交流后,我了解到許多團隊成員并不清楚如何在TypeScript中復用類型。TypeScript允許我們使用typeinterface來定義類型。

當我詢問他們typeinterface之間的區別時,大多數人都表示不清楚,這也就難怪他們不知道如何有效地復用類型了。

type定義的類型可以通過交叉類型(&)來進行復用,而interface定義的類型則可以通過繼承(extends)來實現復用。值得注意的是,typeinterface定義的類型也可以互相復用。下面是一些簡單的示例:

復用type定義的類型:

type Point = {
 x: number;
 y: number;
};

type Coordinate = Point & {
 z: number;
};

復用interface定義的類型:

interface Point {
 x: number;
 y: number;
};

interface Coordinate extends Point {
 z: number;
}

interface復用type定義的類型:


type Point = {
 x: number;
 y: number;
};

interface Coordinate extends Point {
 z: number;
}

type復用interface定義的類型:

interface Point {
 x: number;
 y: number;
};

type Coordinate = Point & {
 z: number;
};

二、復用時只會新增屬性的定義

我還注意到,在類型復用時,團隊成員往往只是簡單地為已有類型新增屬性,而忽略了更高效的復用方式。

例如,有一個已有的類型Props需要復用,但不需要其中的屬性c。在這種情況下,團隊成員會重新定義Props1,僅包含Props中的屬性ab,同時添加新屬性e。


interface Props {
 a: string;
 b: string;
 c: string;
}

interface Props1 {
 a: string;
 b: string;
 e: string;
}

實際上,我們可以利用TypeScript提供的工具類型Omit來更高效地實現這種復用。

interface Props {
 a: string;
 b: string;
 c: string;
}

interface Props1 extends Omit<Props, 'c'> {
 e: string;
}

類似地,工具類型Pick也可以用于實現此類復用。


interface Props {
 a: string;
 b: string;
 c: string;
}

interface Props1 extends Pick<Props, 'a' | 'b'> {
 e: string;
}

OmitPick分別用于排除和選擇類型中的屬性,具體使用哪一個取決于具體需求。

三、未統一使用組件庫的基礎類型

在開發組件庫時,我們經常面臨相似功能組件屬性命名不一致的問題,這不僅影響了組件庫的易用性,也降低了其可維護性。

為了解決這一問題,定義一套統一的基礎類型至關重要。這套基礎類型為組件庫的開發提供了堅實的基礎,確保了所有組件在命名上的一致性。

以表單控件為例,我們可以定義如下基礎類型:


import { CSSProperties } from 'react';

type Size = 'small' | 'middle' | 'large';

interface BaseProps<T> {
 className?: string;
 style?: CSSProperties;
 visible?: boolean;
 size?: Size;
 disabled?: boolean;
 readOnly?: boolean;
 defaultValue?: T;
 value?: T;
 onChange: (value: T) => void;
}

基于這些基礎類型,定義具體組件的屬性類型變得簡單而直接:

interface WInputProps extends BaseProps<string> {
 maxLength?: number;
 showCount?: boolean;
}

通過使用type關鍵字定義基礎類型,我們可以避免類型被意外修改,進而增強代碼的穩定性和可維護性。

四、處理含有不同類型元素的數組

在審查自定義Hook時,我發現團隊成員傾向于返回對象,即使Hook只返回兩個值。

雖然這樣做并非錯誤,但它違背了自定義Hook的一個常見規范:當Hook返回兩個值時,應使用數組返回。

團隊成員解釋說,他們不知道如何定義含有不同類型元素的數組,通常會選擇使用any[],但這會帶來類型安全問題,因此他們選擇返回對象。

實際上,元組是處理這種情況的理想選擇。通過元組,我們可以在一個數組中包含不同類型的元素,同時保持每個元素類型的明確性。

function useMyHook(): [string, number] {
 return ['示例文本', 42];
}

function MyComponent() {
 const [text, number] = useMyHook();
 console.log(text);  // 輸出字符串
 console.log(number);  // 輸出數字
 return null;
}

在這個例子中,useMyHook函數返回一個明確類型的元組,包含一個string和一個number。在MyComponent組件中使用這個Hook時,我們可以通過解構賦值來獲取這兩個不同類型的值,同時保持類型安全。

五、處理參數數量和類型不固定的函數

審查團隊成員封裝的函數時,我發現當函數的參數數量不固定、類型不同或返回值類型不同時,他們傾向于使用any定義參數和返回值。

他們解釋說,他們只知道如何定義參數數量固定、類型相同的函數,對于復雜情況則不知所措,而且不愿意將函數拆分為多個函數。

這正是函數重載發揮作用的場景。通過函數重載,我們可以在同一函數名下定義多個函數實現,根據不同的參數類型、數量或返回類型進行區分。

function greet(name: string): string;
function greet(age: number): string;
function greet(value: any): string {
 if (typeof value === "string") {
   return `Hello, ${value}`;
 } else if (typeof value === "number") {
   return `You are ${value} years old`;
 }
}

在這個例子中,我們為greet函數提供了兩種調用方式,使得函數使用更加靈活,同時保持類型安全。

對于箭頭函數,雖然它們不直接支持函數重載,但我們可以通過定義函數簽名的方式來實現類似的效果。

e GreetFunction = {
 (name: string): string;
 (age: number): string;
};

const greet: GreetFunction = (value: any): string => {
 if (typeof value === "string") {
   return `Hello, ${value}`;
 } else if (typeof value === "number") {
   return `You are ${value} years old.`;
 }
 return '';
};

這種方法利用了類型系統來提供編譯時的類型檢查,模擬了函數重載的效果。

六、組件屬性定義:使用type還是interface?

在審查代碼時,我發現團隊成員在定義組件屬性時既使用type也使用interface。

詢問原因時,他們表示兩者都可以用于定義組件屬性,沒有明顯區別。

由于同名接口會自動合并,而同名類型別名會沖突,我推薦使用interface定義組件屬性。這樣,使用者可以通過declare module語句自由擴展組件屬性,增強了代碼的靈活性和可擴展性。

interface UserInfo {
 name: string;
}
interface UserInfo {
 age: number;
}

const userInfo: UserInfo = { name: "張三", age: 23 };

結語

TypeScript的使用并不困難,關鍵在于理解和應用其提供的強大功能。如果你在使用TypeScript過程中遇到任何問題,不清楚應該使用哪種語法或技巧來解決,歡迎在評論區留言。我們一起探討,共同解決TypeScript中遇到的挑戰。


該文章在 2024/3/21 15:43:04 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved