likes
comments
collection
share

7-语言-TypeScript

作者站长头像
站长
· 阅读数 16

以下是一些TypeScript的高级知识点和例子:

泛型

泛型是一种让函数、类、接口可以适用于不同类型的方法。 举个例子,假设你要编写一个函数来计算数组中的最小值,你可以使用泛型来允许该函数适用于不同类型的数组:

function getMinValue<T>(arr: T[]): T {
  let min = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < min) {
      min = arr[i];
    }
  }
  return min;
}

const numArr = [1, 2, 3, 4, 5];
const strArr = ["apple", "banana", "orange"];
console.log(getMinValue(numArr)); // 1
console.log(getMinValue(strArr)); // "apple"

接口的高级用法

接口不仅可以用于定义对象的形状,还可以定义函数类型、索引类型和类类型等。 举个例子,你可以使用接口定义一个函数类型:

interface AddFunc {
  (a: number, b: number): number;
}

const add: AddFunc = (a, b) => a + b;
console.log(add(1, 2)); // 3

类型别名

类型别名允许你为任何类型定义别名,这样可以使代码更加清晰易读。 举个例子,你可以使用类型别名来定义一个复杂的类型:

type User = {
  id: number;
  name: string;
  age: number;
  contact: {
    email: string;
    phone: string;
  };
};

const user: User = {
  id: 1,
  name: "John",
  age: 30,
  contact: {
    email: "john@example.com",
    phone: "1234567890",
  },
};

类型守卫

类型守卫是一种让你在运行时检查类型的方法,以确定一个变量是哪种类型。 举个例子,你可以使用类型守卫来检查一个变量是否为字符串类型:

function isString(value: unknown): value is string {
  return typeof value === "string";
}

function getStringLength(value: unknown): number {
  if (isString(value)) {
    return value.length;
  }
  throw new Error("Value is not a string");
}

console.log(getStringLength("hello")); // 5

高级类型

TypeScript提供了许多高级类型,如交叉类型、联合类型、类型别名和索引类型等。 这些类型可以让你创建更复杂的类型,以帮助你更好地定义你的代码。 举个例子,你可以使用交叉类型来定义一个包含多个其他类型的新类型:

type Person = {
  name: string;
  age: number;
};

type Employee = {
  id: number;
  salary: number;
};

type Manager = Person & Employee;

const manager: Manager = {
  name: "John",
  age: 35,
  id: 1,
  salary: 50000,
};

Decorators

装饰器是一种能够装饰类、方法、属性或参数的特殊类型声明。它们可以用于修改或扩展类的行为。 举个例子,你可以使用装饰器来添加日志记录或验证:

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

class Calculator {
  @log
  add(a: number, b: number) {
    return a + b;
  }
}

const calculator = new Calculator();
console.log(calculator.add(1, 2)); // Calling add with arguments [1,2],Result: 3

类型推导

TypeScript可以使用类型推导来自动推断变量的类型,以使代码更加简洁和易于阅读。 举个例子,你可以使用类型推导来创建一个包含对象属性的变量:

const person = {
  name: "John",
  age: 30,
};

type Person = typeof person;

const john: Person = {
  name: "John",
  age: 30,
};

Declaration Merging

Declaration Merging是一种将多个类型声明合并在一起的方法,以创建一个新的类型声明。 它可以用于在不修改原始类型定义的情况下扩展类型。 举个例子,你可以使用Declaration Merging来将两个接口合并在一起:

interface Animal {
  name: string;
}

interface Animal {
  age: number;
}

const cat: Animal = {
  name: "Fluffy",
  age: 2,
};

类型断言

类型断言是一种让你在编写代码时覆盖TypeScript的类型检查的方法。 它可以用于在特定情况下强制转换或忽略类型检查。 举个例子,你可以使用类型断言来告诉TypeScript一个变量的类型:

const nameInput = document.getElementById("name") as HTMLInputElement;
const name = nameInput.value;

枚举

枚举是一种用来定义一组命名常量的特殊类型。它可以用于增强代码的可读性和可维护性。 举个例子,你可以使用枚举来定义一组颜色:

enum Color {
  Red,
  Green,
  Blue,
}

const color = Color.Red;
console.log(color); // 0

keyof操作符

keyof操作符可以用于获取一个类型中所有属性名的联合类型。 它可以用于编写通用的函数和类型,以增强代码的可重用性。 举个例子,你可以使用keyof操作符来创建一个通用的选择器函数:

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

const person = {
  name: "John",
  age: 30,
};

console.log(select(person, "name")); // "John"
console.log(select(person, "age")); // 30

迭代器和生成器

TypeScript支持迭代器和生成器,它们是一种用于处理集合的强大工具。 它们可以用于创建可重用的代码和进行基于集合的异步操作。 举个例子,你可以使用生成器来创建一个异步迭代器:

async function* generate() {
  let i = 0;
  while (i < 3) {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    yield i++;
  }
}

(async () => {
  for await (const item of generate()) {
    console.log(item);
  }
})();

最后

TypeScript在前端领域的应用情况越来越广泛,主流三大框架目前都已经支持,另外像Redux、Jest、Lodash等等许多开源库和工具也使用TypeScript来提供更好的API文档和类型定义,TypeScript的生态系统非常强大且不断增长。