You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TypeScript尖括号用法困惑及相关场景咨询

Great question! You already have a solid grasp of the core uses of angle brackets (<>) in TypeScript for generics and array types, so let's dive into the other scenarios—including the "prepended" case you're curious about.

Other Uses of Angle Brackets (<>) in TypeScript

1. Prepended Angle Brackets: Type Assertions (Type Casting)

This is the "prepended" scenario you mentioned. When you put <Type> before a value, you're telling TypeScript: "Trust me, I know this value is of type Type." It’s a way to override the compiler’s inference when you have more context than it does.

Example:

// Suppose we get a value from an API that TypeScript sees as `unknown`
const apiResponse: unknown = "TypeScript is cool";

// Use angle brackets to assert it's a string
const message = <string>apiResponse;
console.log(message.toUpperCase()); // Works perfectly

Note: This syntax conflicts with JSX (since JSX uses <> for elements), so in .tsx files, stick to the as syntax instead: const message = apiResponse as string;—both do the exact same thing, just with context-friendly syntax.

2. Generic Classes & Interfaces

You’ve used generics with functions, but they’re equally useful for creating reusable, type-safe classes and interfaces.

Generic Class Example:

class Storage<T> {
  private items: T[] = [];

  addItem(item: T): void {
    this.items.push(item);
  }

  getItems(): T[] {
    return this.items;
  }
}

// Create a storage specifically for numbers
const numberStorage = new Storage<number>();
numberStorage.addItem(10);
numberStorage.addItem(20);
console.log(numberStorage.getItems()); // [10, 20]

Generic Interface Example:

interface ApiResponse<T> {
  success: boolean;
  data: T;
  error?: string;
}

// Use it to define a response shape for user data
type UserResponse = ApiResponse<{ id: number; name: string }>;

const validResponse: UserResponse = {
  success: true,
  data: { id: 1, name: "Charlie" }
};

3. Built-in Generic Utility Types

TypeScript includes a set of pre-built generic tools that use angle brackets to transform existing types. These save you from writing repetitive type definitions.

Some common utility types:

  • Partial<T>: Makes all properties of T optional
  • Readonly<T>: Makes all properties of T read-only
  • Pick<T, K>: Selects specific properties K from T
  • Omit<T, K>: Removes specific properties K from T

Example:

interface Product {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
}

// Create a type for partial product updates (only include changed properties)
type ProductUpdate = Partial<Product>;
const update: ProductUpdate = { price: 19.99 };

// Create a simplified type with only id and name
type ProductPreview = Pick<Product, "id" | "name">;
const preview: ProductPreview = { id: 2, name: "Laptop" };

4. JSX Element Generics (in .tsx Files)

In React or other JSX-based projects, you’ll use angle brackets for generic components. Just remember: you can’t use the prepended type assertion syntax here (it clashes with JSX tags), but generics on components work seamlessly.

Example:

// A generic component that renders a list of items
function List<T>({ items, renderItem }: { items: T[]; renderItem: (item: T) => JSX.Element }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{renderItem(item)}</li>
      ))}
    </ul>
  );
}

// Use it with a list of strings
<List<string>
  items={["Apple", "Banana", "Cherry"]}
  renderItem={(fruit) => <span>{fruit}</span>}
/>

5. Module-Level Generic Type Imports

Occasionally, you might import a generic type from a module and specify its type parameter when defining a new type:

// Import a generic type from an external module
import type { GenericCollection } from "./collections";

// Define a specific version of the generic type
type NumberCollection = GenericCollection<number>;

内容的提问来源于stack exchange,提问作者SeBe

火山引擎 最新活动