You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在TypeScript中何时使用泛型类?附文档示例实操疑问

Understanding and Using the Generic 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 (wasSuccessful boolean)
  • Exactly what went wrong (error of type T, 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 the error property.
  • Cleaner code: Avoids nested try/catch blocks and makes error handling more intentional.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:12:44