在TypeScript中何时使用泛型类?附文档示例实操疑问
Result<T> Class Got it, let's break down how this TypeScript Result<T> class works and how to put it to use in real-world scenarios—this pattern is super handy for handling success/failure states cleanly, no more guessing if an operation worked or relying on vague error handling!
First, let's recap the code you shared with a complete clone method (since the original had a placeholder):
class Result<T> { constructor(public wasSuccessful: boolean, public error: T) {} public clone(): Result<T> { return new Result(this.wasSuccessful, this.error); } } // Example instantiation let r1 = new Result(false, 'error: 42');
What This Pattern Solves
This is a result type pattern, designed to explicitly represent the outcome of an operation. Instead of throwing exceptions or returning null/undefined when something goes wrong, it gives you a structured object that tells you:
- Whether the operation succeeded (
wasSuccessfulboolean) - Exactly what went wrong (
errorof typeT, which can be a string, error object, or custom error type)
It forces you to handle both success and failure states upfront, making your code more predictable and maintainable.
Real-World Use Cases
1. API Response Handling
When fetching data from an API, this pattern eliminates messy try/catch blocks scattered throughout your code. Instead, you wrap the operation and return a Result:
async function fetchProduct(productId: string): Promise<Result<string>> { try { const response = await fetch(`/api/products/${productId}`); if (!response.ok) { return new Result(false, `Request failed: ${response.status} ${response.statusText}`); } // If successful, we don't need an error await response.json(); return new Result(true, ''); } catch (err) { return new Result(false, `Network error: ${(err as Error).message}`); } } // Using the function const productResult = await fetchProduct('123'); if (!productResult.wasSuccessful) { console.error('Failed to load product:', productResult.error); // Show user-friendly error message, retry, or redirect } else { console.log('Product loaded successfully!'); // Render product data }
2. Form Validation
For form inputs, you can use Result to return specific validation errors instead of just a boolean:
function validatePassword(password: string): Result<string> { if (password.length < 8) { return new Result(false, 'Password must be at least 8 characters long'); } if (!/[A-Z]/.test(password)) { return new Result(false, 'Password must include at least one uppercase letter'); } return new Result(true, ''); } const passwordResult = validatePassword('weakpass'); if (!passwordResult.wasSuccessful) { alert(passwordResult.error); }
3. Extending for Success Data
You can tweak the class to hold success data too, making it even more flexible:
class Result<T, U> { constructor( public wasSuccessful: boolean, public error?: T, public data?: U ) {} public clone(): Result<T, U> { return new Result(this.wasSuccessful, this.error, this.data); } } // Success case with data const successResult = new Result(true, undefined, { id: 456, name: 'Wireless Headphones' }); // Failure case with error const failureResult = new Result(false, 'Database connection timed out');
Key Benefits
- Type safety: TypeScript ensures you handle the error (and success data, if extended) with the correct type.
- Explicit state: No more confusion about why a value is
null—you get clear context from theerrorproperty. - Cleaner code: Avoids nested try/catch blocks and makes error handling more intentional.
内容的提问来源于stack exchange,提问作者Karabah

