Presupuestador_web/shared/lib/contexts/common/domain/entities/Result.ts
2024-04-23 17:29:38 +02:00

64 lines
1.5 KiB
TypeScript

export class Result<T, E extends Error = Error> {
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<U>(object?: U): Result<U, never> {
return new Result<U, never>({ isSuccess: true, object });
}
public static fail<E extends Error = Error>(error?: E): Result<never, E> {
return new Result<never, E>({ isSuccess: false, error });
}
public static combine(results: Result<any, any>[]): Result<any, any> {
for (const result of results) {
if (result.isFailure) {
return result;
}
}
return Result.ok<any>();
}
}