export class Result { protected readonly _object?: T; protected readonly _error?: E; public readonly isSuccess: boolean; public readonly isFailure: boolean; protected constructor(props: { isSuccess: boolean; error?: E; object?: T }) { const { isSuccess, error, object } = props; if (isSuccess && error) { throw new Error( `InvalidOperation: A result cannot be successful and contain an error`, ); } if (!isSuccess && !error) { throw new Error( `InvalidOperation: A failing result needs to contain an error message`, ); } this.isSuccess = isSuccess; this.isFailure = !isSuccess; this._error = error; this._object = object; Object.freeze(this); } public get object(): T { if (this.isFailure) { throw new Error(`Result is not successful`); } return this._object as T; } public get error(): E { if (this.isSuccess) { throw new Error(`Result is not error`); } return this._error as E; } // Constructores públicos public static ok(object?: U): Result { return new Result({ isSuccess: true, object }); } public static fail(error?: E): Result { return new Result({ isSuccess: false, error }); } public static combine(results: Result[]): Result { for (const result of results) { if (result.isFailure) { return result; } } return Result.ok(); } }