Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/194/nullish result value #195

Merged
merged 2 commits into from
Nov 19, 2024
Merged

Conversation

4lessandrodev
Copy link
Owner

Documentation of the Changes Implemented

This update focuses on improving the typing and behavior of the Result class, especially in failure (Fail) cases. Changes were made to explicitly set the generic type of the value (T) in failures to null, and new methods were introduced to simplify validations and make the code safer and more readable.


Main Changes

1. Typing Change in Failures

  • The generic type T in Fail is now explicitly set to null:
    public static fail<D = string, M = {}>(error?: D, metaData?: M): Result<null, D, M>;
  • This ensures that in a failure state, the value of a Result (value()) will always be null.

2. Introduction of the isNull Method

  • A new method has been added to check if the value (#data) of a Result is null:
    isNull(): boolean {
        return this.#data === null || this.#isFail;
    }
  • This method helps explicitly differentiate null values from success and failure states.

3. Adjustments to Creation Methods and Adapters

  • All creation methods (create) and adapters now explicitly return Result<T | null, ...>:
    public static create(props: Props): IResult<ValueObject<Props> | null>;

Example: Using Result After the Changes

Creating a Failure Result

const result = Result.fail("Invalid operation");

// Explicitly checking if the value is null or a failure
if (result.isNull()) {
    console.log("The result is null or in a failure state.");
} else {
    console.log("The result value is:", result.value());
}

Handling Possible Failures in a Factory

class UserEntity {
    private constructor(public readonly name: string) {}

    public static create(name: string): IResult<UserEntity | null> {
        if (!name) return Result.fail("Name is required");
        return Result.Ok(new UserEntity(name));
    }
}

const userResult = UserEntity.create("");

if (userResult.isOk() && !userResult.isNull()) {
    console.log("User created:", userResult.value()?.name);
} else {
    console.error("Error creating user:", userResult.error());
}

Example: Adapters Returning null

Conversion Adapter

class CustomAdapter implements IAdapter<number, string, string> {
    build(input: number): IResult<string | null> {
        if (input < 0) return Result.fail("Negative values are not allowed");
        return Result.Ok(`Value: ${input}`);
    }
}

const adapter = new CustomAdapter();
const result = adapter.build(-1);

if (result.isNull()) {
    console.error("Failed:", result.error());
} else {
    console.log("Success:", result.value());
}

Summary of Improvements

  1. Explicit Typing in Failures:

    • The value (T) is always null in failure states, improving type safety.
  2. New isNull Method:

    • Simplifies validation of null results or failure states.
  3. Consistency in Creation Methods:

    • All creation methods now return Result<T | null> where applicable.
  4. Safer and More Readable Code:

    • The new API encourages clear and explicit checks, reducing ambiguities.

Version Release

This fix will be published in a beta version for testing: 1.23.5.beta-0.

#194

@4lessandrodev 4lessandrodev merged commit 6a0889b into main Nov 19, 2024
1 check passed
@4lessandrodev 4lessandrodev deleted the fix/194/nullish-result-value branch December 15, 2024 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant