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

发布时间 2023-06-05 09:53:59作者: 晓风晓浪

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")