那些前端代码中的尖括号<>你看得懂吗?

1. 泛型(Generics)

泛型(Generics)是 TypeScript 中的一种功能,允许你在声明时不指定具体的类型,而是在使用时指定具体类型,从而提高代码的复用性和灵活性。

示例:泛型函数

function identity<T>(arg: T): T {
  return arg;
}

const result = identity(42);  // T 被推导为 number
const result2 = identity("hello");  // T 被推导为 string
  • identity<T> 是一个泛型函数,T 代表一个类型参数,表示函数接受的参数类型和返回值类型都是 T
  • 在调用时,TypeScript 会根据传入的参数自动推导 T 的具体类型。

示例:泛型接口

interface Box<T> {
  value: T;
}

const numberBox: Box<number> = { value: 42 };
const stringBox: Box<string> = { value: "hello" };
  • Box<T> 是一个泛型接口,表示 value 属性的类型是 T,可以在实例化时指定具体类型。

示例:泛型类

class Container<T> {
  private items: T[] = [];
  
  addItem(item: T): void {
    this.items.push(item);
  }
  
  getItems(): T[] {
    return this.items;
  }
}

const numberContainer = new Container<number>();
numberContainer.addItem(1);
console.log(numberContainer.getItems()); // 输出: [1]

const stringContainer = new Container<string>();
stringContainer.addItem("hello");
console.log(stringContainer.getItems()); // 输出: ["hello"]
  • Container<T> 是一个泛型类,允许我们在创建实例时指定元素类型。

2. 箭头函数中的泛型

在箭头函数中使用泛型可以提供灵活的类型推导,尤其是函数签名复杂时,使用泛型让函数更具通用性。

示例:箭头函数中的泛型

const add = <T extends number | string>(a: T, b: T): T => {
  return (a + b) as T;
};

const sum = add(5, 10);  // T 被推导为 number
const concat = add("Hello, ", "World!");  // T 被推导为 string
  • 在箭头函数中,<T extends number | string> 限制了 T 只能是 numberstring 类型,确保了泛型的类型安全。
  • 该函数可以接受 number 类型或 string 类型的两个参数,并返回相同类型的结果。

示例:复杂函数签名中的泛型

type ApiRequest<F, T> = (
  formData: F,
  page: { current: number; pageSize: number }
) => Promise<{ total: number; list: T[] }>;

const request: ApiRequest<{ searchTerm: string }, { id: number; name: string }> = async (formData, page) => {
  const data = await fetchData(formData, page);
  return {
    total: data.total,
    list: data.items,
  };
};
  • ApiRequest<F, T> 是一个泛型类型,F 是表单数据类型,T 是返回数据类型。通过泛型来定义请求函数的参数和返回值类型。
  • request 实例中,formData 被指定为 { searchTerm: string }T 被指定为 { id: number; name: string }

3. 类型断言(Type Assertion)

类型断言用于告诉 TypeScript 编译器一个值的类型,即使编译器无法推导出类型。这可以用来确保在某些情况下类型是正确的。

示例:类型断言

let someValue: any = "Hello, TypeScript!";
let strLength: number = (<string>someValue).length;  // 断言为 string 类型
console.log(strLength);  // 输出: 18
  • <string> 是类型断言,表示 someValue 是一个 string 类型,尽管其类型是 any

示例:使用 as 语法进行类型断言

let someValue: any = { id: 1, name: "Item" };
let itemName: string = (someValue as { name: string }).name;
console.log(itemName);  // 输出: "Item"
  • 使用 as 语法进行类型断言,告诉 TypeScript someValue 应该被视为 { name: string } 类型。

注意:

  • React 中,类型断言常用于事件处理或 DOM 元素操作,避免类型推导错误。

4. React Props 类型声明(泛型)

在 React 中,我们可以使用 泛型 来声明组件的 Props 类型,使得组件更加灵活和类型安全。

示例:React 组件的泛型 Props

interface MyComponentProps<T> {
  value: T;
}

const MyComponent = <T,>({ value }: MyComponentProps<T>) => {
  return <div>{value}</div>;
};

const App = () => {
  return (
    <>
      <MyComponent value={42} />
      <MyComponent value={"Hello"} />
    </>
  );
};
  • MyComponent 是一个泛型组件,<T,> 使组件接受任意类型的 value 属性。
  • 当使用 MyComponent 时,value 的类型可以是 numberstring,根据传入的值自动推导。

示例:带默认类型的泛型 Props

interface MyComponentProps<T = number> {
  value: T;
}

const MyComponent = <T,>({ value }: MyComponentProps<T>) => {
  return <div>{value}</div>;
};

const App = () => {
  return (
    <>
      <MyComponent value={42} />
      <MyComponent value={"Hello"} />
    </>
  );
};
  • MyComponentProps<T = number>T 提供了默认类型 number,但你依然可以在实例化组件时指定不同的类型。

5. 数组类型声明

在 TypeScript 中,使用尖括号来声明数组的元素类型。

示例:数组类型声明

let numbers: Array<number> = [1, 2, 3, 4];
let strings: string[] = ["a", "b", "c"];
  • Array<number>string[] 是等价的,表示声明一个数组,该数组的每个元素都属于 numberstring 类型。

示例:泛型与数组类型结合

function getArray<T>(items: T[]): T[] {
  return new Array().concat(items);
}

const numArray = getArray([1, 2, 3]);  // numArray 类型是 number[]
const strArray = getArray(["a", "b", "c"]);  // strArray 类型是 string[]
  • getArray<T> 是一个泛型函数,它接受一个数组并返回相同类型的数组。

总结

  1. 泛型(Generics):提高函数、类、接口的复用性和灵活性,允许函数、类或接口在声明时不指定类型,在使用时指定类型。
  2. 箭头函数中的泛型:在箭头函数中使用泛型,使得函数签名灵活,尤其在函数逻辑复杂时,能够根据具体类型进行操作。
  3. 类型断言(Type Assertion):用于告诉 TypeScript 编译器某个值的类型,用于修正编译器推导的类型,尤其是在某些类型无法直接推导时。
  4. React Props 类型声明(泛型):在 React 中使用泛型声明组件的 Props 类型,使组件能够接受不同类型的 props,从而提高组件的灵活性。
  5. 数组类型声明:使用尖括号声明数组的元素类型,使得数组的每个元素类型一致。

这些技术可以大大提高代码的类型安全性、可读性和可维护性,尤其在大型项目中,泛型的使用使得开发更加灵活、强大。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容