64 lines
1.5 KiB
TypeScript
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>();
|
|
}
|
|
}
|