专业人士使用的7个秘密TypeScript技巧

65 阅读2分钟

TypeScript是一种出色的工具,可以让我们的生活更轻松并避免错误,但有时使用起来会让人不知所措。

动图压倒

本文概述了所有专业人士都使用的 7 个TypeScript技巧,它们将使您的生活更轻松。

(更多优质教程:java567.com,搜"ts")

1. 类型推断

Typescript足够聪明,可以在您帮助缩小数据类型时推断数据类型。

 enum CounterActionType {
   Increment = "INCREMENT",
   IncrementBy = "INCREMENT_BY",
 }
 ​
 interface IncrementAction {
   type: CounterActionType.Increment;
 }
 ​
 interface IncrementByAction {
   type: CounterActionType.IncrementBy;
   payload: number;
 }
 ​
 type CounterAction =
   | IncrementAction
   | IncrementByAction;
 ​
 function reducer(state: number, action: CounterAction) {
   switch (action.type) {
     case CounterActionType.Increment:
       // TS infers that the action is IncrementAction
       // & has no payload
       return state + 1;
     case CounterActionType.IncrementBy:
       // TS infers that the action is IncrementByAction
       // & has a number as a payload
       return state + action.payload;
     default:
       return state;
   }
 }

如上所示,TypeScript根据属性推断操作的类型type,因此您不需要检查是否payload存在。

2.文字类型

通常您需要变量的特定值,这就是文字类型派上用场的地方。

 type Status = "idle" | "loading" | "success" | "error";

它也适用于数字:

 type Review = 1 | 2 | 3 | 4 | 5;
 ​
 // or better yet:
 const reviewMap = {
   terrible: 1,
   average: 2,
   good: 3,
   great: 4,
   incredible: 5,
 } as const;
 ​
 // This will generate the same type as above,
 // but it's much more maintainable
 type Review = typeof reviewMap[keyof typeof reviewMap];

3.类型守卫

类型保护是另一种缩小变量类型的方法:

 function isNumber(value: any): value is number {
   return typeof value === "number";
 }
 ​
 const validateAge = (age: any) => {
   if (isNumber(age)) {
     // validation logic
     // ...
   } else {
     console.error("The age must be a number");
   }
 };

注意:在上面的示例中,最好使用:

 const validateAge = (age: number) => {
   // ...
 };

这个例子是为了展示类型保护是如何工作的一个简化。

4. 索引签名

当对象中有动态键时,可以使用* *索引签名**来定义其类型:

 enum PaticipationStatus {
   Joined = "JOINED",
   Left = "LEFT",
   Pending = "PENDING",
 }
 ​
 interface ParticipantData {
   [id: string]: PaticipationStatus;
 }
 ​
 const participants: ParticipantData = {
   id1: PaticipationStatus.Joined,
   id2: PaticipationStatus.Left,
   id3: PaticipationStatus.Pending,
   // ...
 };

5.泛型

泛型是一个强大的工具,可以让你的代码更容易重用。它允许您定义一个类型,该类型将由您的函数的使用决定

在以下示例中,T是通用类型:

 const clone = <T>(object: T) => {
   const clonedObject: T = JSON.parse(JSON.stringify(object));
   return clonedObject;
 };
 ​
 const obj = {
   a: 1,
   b: {
     c: 3,
   },
 };
 ​
 const obj2 = clone(obj);

6. 不可变类型

您可以通过添加as const. 这确保您不会意外更改值。

 const ErrorMessages = {
   InvalidEmail: "Invalid email",
   InvalidPassword: "Invalid password",
   // ...
 } as const;
 ​
 // This will throw an error
 ErrorMessages.InvalidEmail = "New error message";

7. 部分、选择、省略和必需类型

通常在处理服务器本地数据时,您需要将某些属性设置为可选必需的

而不是使用相同数据的略微更改版本定义数百个接口。您可以使用Partial, Pick, Omit&Required类型来做到这一点。

 interface User {
   name: string;
   age?: number;
   email: string;
 }
 ​
 type PartialUser = Partial<User>;
 type PickUser = Pick<User, "name" | "age">;
 type OmitUser = Omit<User, "age">;
 type RequiredUser = Required<User>;
 ​
 // PartialUser is equivalent to:
 // interface PartialUser {
 //   name?: string;
 //   age?: number;
 //   email?: string;
 // }
 ​
 // PickUser is equivalent to:
 // interface PickUser {
 //   name: string;
 //   age?: number;
 // }
 ​
 // OmitUser is equivalent to:
 // interface OmitUser {
 //   name: string;
 //   email: string;
 // }
 ​
 // RequiredUser is equivalent to:
 // interface RequiredUser {
 //   name: string;
 //   age: number;
 //   email: string;
 // }

当然,您可以使用交集来组合它们:

 type A = B & C;

其中B&C是任何类型。

这就是所有的人!🎉

(更多优质教程:java567.com,搜"ts")