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.
<>) 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 ofToptionalReadonly<T>: Makes all properties ofTread-onlyPick<T, K>: Selects specific propertiesKfromTOmit<T, K>: Removes specific propertiesKfromT
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




