10个超级实用的typescript使用技巧

1,394 阅读3分钟

freysteinn-g-jonsson-s94zCnADcUs-unsplash.jpg

概览:在实际的开发工作过程中,积累了一些常见又超级好用的 typescript 技巧和代码片段,包括整理的其他大神的ts使用技巧,今天筛选了 10+ 个,以供大家参考。

使用交叉类型来合并多个类型

type User = {
  name: string;
};

type Admin = {
  role: string;
};

type UserAndAdmin = User & Admin;

const user: UserAndAdmin = {
  name: "John",
  role: "admin"
};

使用联合类型来允许多个类型

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

function showMessage(status: Status, message: string) {
  // ...
}

showMessage("success", "Operation completed successfully");

使用类型守卫来判断变量的类型

type User = {
  name: string;
};

type Admin = {
  name: string;
  role: string;
};

function greet(user: User | Admin) {
  if ("role" in user) {
    console.log(`Hello, ${user.name}, you are an admin`);
  } else {
    console.log(`Hello, ${user.name}`);
  }
}

使用optional chaining操作符(?.)和nullish coalescing操作符(??)来简化代码

const user = {
  name: "John",
  address: {
    city: null
  }
};

const cityName = user?.address?.city ?? "unknown";

使用装饰器来扩展类和方法的行为

function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function(...args: any[]) {
    console.log(`Calling method ${propertyKey} with arguments: ${JSON.stringify(args)}`);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

class User {
  constructor(public name: string, public age: number) {}

  @log
  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old`);
  }
}

const user = new User("John", 30);
user.greet();

使用 Record 来定义键值对类型

type AgeMap = Record<string, number>;

const ages: AgeMap = {
  John: 30,
  Mary: 25,
  Mike: 35,
};

使用模板字符串和 keyof 来生成属性名称

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

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const person: Person = { name: "John", age: 30 };
const propertyName = "name";
console.log(getProperty(person, propertyName as keyof Person));
console.log(getProperty(person, "age"));

在上面的代码中,我们使用模板字符串和 keyof 操作符来生成属性名称,并将其作为参数传递给函数 getProperty。

使用类型保护来检查变量的类型

interface Dog {
  name: string;
  breed: string;
}

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

function isDog(pet: Dog | Cat): pet is Dog {
  return (pet as Dog).breed !== undefined;
}

const dog: Dog = { name: "Max", breed: "Labrador" };
const cat: Cat = { name: "Whiskers", age: 3 };

console.log(isDog(dog)); // true
console.log(isDog(cat)); // false

在上面的代码中,我们使用 isDog 函数来检查变量 pet 是否是 Dog 类型。

使用 Exclude 和 Extract 来过滤类型

type T1 = string | number | boolean;
type T2 = Exclude<T1, boolean>;
type T3 = Extract<T1, string>;

在上面的代码中,我们使用 Exclude 和 Extract 类型来过滤 T1 类型。T2 类型将移除 boolean 类型,而 T3 类型将只保留 string 类型。

使用 Partial 和 Required 来转换类型

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

type PartialPerson = Partial<Person>;
type RequiredPerson = Required<PartialPerson>;

在上面的代码中,我们使用 Partial 和 Required 类型来转换类型。PartialPerson 类型将转换为可选的属性,而 RequiredPerson 类型将转换为必填的属性。

使用 Pick 和 Omit 来选择和排除属性

interface Person {
  name: string;
  age: number;
  address: string;
}

type PersonNameAge = Pick<Person, "name" | "age">;
type PersonWithoutAddress = Omit<Person, "address">;

在上面的代码中,我们使用 Pick 和 Omit 类型来选择和排除属性。PersonNameAge 类型将只保留 name 和 age 属性,而 PersonWithoutAddress 类型将排除 address 属性。

使用 as const 来创建只读数组和对象

const arr = ["foo", "bar"] as const;
const obj = { name: "John", age: 30 } as const;

在上面的代码中,我们使用 as const 来创建只读数组和对象。arr 和 obj 将不可修改。

使用 Readonly 来使对象的所有属性变为只读

interface Person {
  name: string;
  age: number;
  address: string;
}

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = { name: "John", age: 30, address: "123 Main St." };
person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.

在上面的代码中,我们使用 Readonly 来使对象的所有属性变为只读。ReadonlyPerson 类型将具有与 Person 相同的属性,但所有属性都是只读的。

使用 Required 来使对象的所有属性变为必需的

interface Person {
  name?: string;
  age?: number;
  address?: string;
}

type RequiredPerson = Required<Person>;

const person: RequiredPerson = { name: "John", age: 30, address: "123 Main St." };

在上面的代码中,我们使用 Required 来使对象的所有属性变为必需的。RequiredPerson 类型将具有与 Person 相同的属性,但所有属性都是必需的。

使用 NonNullable 来移除对象的所有可空属性

interface Person {
  name?: string;
  age?: number | null;
  address?: string | null;
}

type NonNullablePerson = NonNullable<Person>;

const person: NonNullablePerson = { name: "John", age: 30, address: "123 Main St." };

系列文章

我的更多前端资讯

欢迎大家技术交流 资料分享 摸鱼 求助皆可 —链接