export class Result { private constructor( private readonly _value?: T, private readonly _error?: E, private readonly _isSuccess: boolean = true ) {} static ok(value: T): Result { return new Result(value, undefined, true); } static err(error: E): Result { return new Result(undefined, error, false); } isOk(): boolean { return this._isSuccess; } isErr(): boolean { return !this._isSuccess; } unwrap(): T { if (!this._isSuccess) { throw new Error('Called unwrap on an error result'); } return this._value!; } unwrapOr(defaultValue: T): T { return this._isSuccess ? this._value! : defaultValue; } unwrapErr(): E { if (this._isSuccess) { throw new Error('Called unwrapErr on a success result'); } return this._error!; } map(fn: (value: T) => U): Result { if (this._isSuccess) { return Result.ok(fn(this._value!)); } return Result.err(this._error!); } mapErr(fn: (error: E) => F): Result { if (!this._isSuccess) { return Result.err(fn(this._error!)); } return Result.ok(this._value!); } andThen(fn: (value: T) => Result): Result { if (this._isSuccess) { return fn(this._value!); } return Result.err(this._error!); } /** * Direct access to the value (for testing convenience). * Prefer using unwrap() in production code. */ get value(): T | undefined { return this._value; } /** * Direct access to the error (for testing convenience). * Prefer using unwrapErr() in production code. */ get error(): E | undefined { return this._error; } }