13 個Typescript 實用型別:開發人員的備忘單

前端小智發表於2022-05-31
作者:Rahul Sharma
譯者:前端小智
來源:dev

在型別檢查方面,Typescript非常強大,但有時當一些型別是其他型別的子集,而你需要為它們定義型別檢查時,它就變得很乏味。

舉個例子,你有2個響應型別。

interface UserProfileResponse {
  id: number;
  name: string;
  email: string;
  phone: string;
  avatar: string;
}

interface LoginResponse {
  id: number;
  name: string;
}

我們可以為 UserProfileResponse 定義型別,併為 LoginResponse 挑選一些屬性,而不是定義相同上下文的 LoginResponse 和 UserProfileResponse 的型別。

type LoginResponse = Pick<UserProfileResponse, "id" | "name">;

讓我們來了解一些可以幫助你寫出更好的程式碼的實用函式。

Uppercase

構建一個型別的所有屬性都設定為大寫的型別。

type Role = "admin" | "user" | "guest";

// Bad practice ?
type UppercaseRole = "ADMIN" | "USER" | "GUEST";

// Good practice ✅
type UppercaseRole = Uppercase<Role>; // "ADMIN" | "USER" | "GUEST"

Lowercase

構建一個型別的所有屬性都設定為小寫的型別。與 Uppercase 相反。

type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ?
type LowercaseRole = "admin" | "user" | "guest";

// Good practice ✅
type LowercaseRole = Lowercase<Role>; // "admin" | "user" | "guest"

Capitalize

構建一個型別的所有屬性都設定為大寫開頭的型別。

type Role = "admin" | "user" | "guest";

// Bad practice ?
type CapitalizeRole = "Admin" | "User" | "Guest";

// Good practice ✅
type CapitalizeRole = Capitalize<Role>; // "Admin" | "User" | "Guest"

Uncapitalize

構建一個型別的所有屬性都設定為非大寫的型別。與Capitalize相反。

type Role = "Admin" | "User" | "Guest";

// Bad practice ?
type UncapitalizeRole = "admin" | "user" | "guest";

// Good practice ✅
type UncapitalizeRole = Uncapitalize<Role>; // "admin" | "user" | "guest"

Partial

構建一個型別的所有屬性都設定為可選的型別。

interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ?
interface PartialUser {
  name?: string;
  age?: number;
  password?: string;
}

// Good practice ✅
type PartialUser = Partial<User>;

Required

構建一個由Type的所有屬性組成的型別,設定為必填。與Partial相反。

interface User {
  name?: string;
  age?: number;
  password?: string;
}

// Bad practice ?
interface RequiredUser {
  name: string;
  age: number;
  password: string;
}

// Good practice ✅
type RequiredUser = Required<User>;

Readonly

構建一個由Type的所有屬性組成的型別,設定為只讀。

interface User {
  role: string;
}

// Bad practice ?
const user: User = { role: "ADMIN" };
user.role = "USER";

// Good practice ✅
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = { role: "ADMIN" };
user.role = "USER"; // Error: Cannot assign to 'role' because it is a read-only property.

Record

Record是一個很好用的工具型別。他會將一個型別的所有屬性值都對映到另一個型別上並創造一個新的型別,

interface Address {
  street: string;
  pin: number;
}

interface Addresses {
  home: Address;
  office: Address;
}

// 或者
type AddressesRecord = Record<"home" | "office", Address>;

Pick

從一個複合型別中,取出幾個想要的型別的組合

interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ?
interface UserPartial {
  name: string;
  age: number;
}

// Good practice ✅
type UserPartial = Pick<User, "name" | "age">;

Omit

以一個型別為基礎支援剔除某些屬性,然後返回一個新型別。

interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ?
interface UserPartial {
  name: string;
  age: number;
}

// Good practice ✅
type UserPartial = Omit<User, "password">;

Exclude

Exclude<T, U>,該工具型別能夠從型別T中剔除所有可以賦值給型別U的型別。

type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ?
type NonAdminRole = "USER" | "GUEST";

// Good practice ✅
type NonAdmin = Exclude<Role, "ADMIN">; // "USER" | "GUEST"

Extract

Extract 的功能,與 Exclude 相反,它是 提取 T 中可以賦值給 U 的型別。

type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ?
type AdminRole = "ADMIN";

// Good practice ✅
type Admin = Extract<Role, "ADMIN">; // "ADMIN"

NonNullable

構建一個型別的所有屬性都設定為非空的型別。

type Role = "ADMIN" | "USER" | null;

// Bad practice ?
type NonNullableRole = "ADMIN" | "USER";

// Good practice ✅
type NonNullableRole = NonNullable<Role>; // "ADMIN" | "USER"

編輯中可能存在的bug沒法實時知道,事後為了解決這些bug,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

原文:https://dev.to/devsmitra/13-t...

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章