DEV Community

Cover image for Introducing Result & Option Constructor Control Flow in @rslike/std 3.1.0
Vitali Haradkou
Vitali Haradkou

Posted on

Introducing Result & Option Constructor Control Flow in @rslike/std 3.1.0

RSLike is a collection of packages that ensures the safety of your Typescript/Javascript code without undefined/null checks.

The latest release of @rslike/std brings powerful new features and important fixes to enhance functional and OOP programming in TypeScript. In version 3.1.0, we've introduced improved control flow for Result and Option constructors, along with several fixes and updates.

Result & Option Constructors Control Flow

Now, you can create Result or Option instances using either Promises or direct return values. This makes error handling more flexible and intuitive.

import { Result, Option } from "@rslike/std";

// Constructor control flow
const result = new Result((ok, err) => {
  if (Math.random() > 0.5) {
    ok(42);
  } else {
    err("error");
  }
});

// Return control flow
const result2 = new Result(() => {
  if (Math.random() > 0.5) {
    return 42;
  } else {
    throw new Error("error");
  }
});

console.log(result2); // Result<42, Error> or Result<number, Error>

const option = new Option((some, none) => {
  if (Math.random() > 0.5) {
    some(42);
  } else {
    none();
  }
});

const opt2 = new Option(() => {
  throw new Error("error");
});

console.log(opt2.isNone()); // true
Enter fullscreen mode Exit fullscreen mode

⚠ Note: Async functions and Promise return statements are not supported and will throw an error. Use Result.fromPromise instead.

import { Result } from "@rslike/std";

// ❌ Incorrect usage
new Result((ok, err) => {
  ok(Promise.resolve(42)); // Throws an error
});
// ❌ Incorrect usage
new Result(() => {
  return Promise.resolve(42); // Throws an error
});
// ❌ Incorrect usage
new Result(async () => {
  return "qwe"; // Throws an error
});

// ✅ Correct usage
async function someFn(){ /** implementation */} 
const result = await Result.fromPromise(someFn())

// ✅✅ Better usage - combine Result and Option for function - Bind
async function someFn(): number { /** implementation */} 
const binded = Bind(someFn)

const r = await binded() // Result<Option<number>>
Enter fullscreen mode Exit fullscreen mode

Option.fromPromise & Option.fromAsync

Now you can safely create an Option from an async function or a Promise using the new Option.fromPromise or Option.fromAsync methods. Result has already been implemented in this functionality, so we retranslate the same logic from the Result class.

JS compatibility

Migrated status for Result and Option from enum to object.

Added assertion for passing constructor executor argument in Result and Option.

Fixed types for well-known symbols: Symbol.split, Symbol.search, Symbol.iterator, and Symbol.asyncIterator.

// before (Symbol.iterator)
const a = Some([1,2,3])
for(const el of a) {
       // ^ type el: number
}
// before (Symbol.asyncIterator)
for await (const el of a) { // no throws
       // ^ type el: number
}

// after (Symbol.iterator)
const a = Some([1,2,3])
for(const el of a) {
       // ^ type el: 1 | 2 | 3
}

// after (Symbol.asyncIterator)
for await (const el of a) { // throws, array does not implement Symbol.asyncIterator function
       // ^ type el: never
}

// before (Symbol.split)
const nonSplittable = Ok(5)
'some long string'.split(nonSplittable) // Ok in types, throws in execution

// after (Symbol.split)
const nonSplittable = Ok(5)
'some long string'.split(nonSplittable) // Error in types, throws in execution

'string to split'.split(Ok('to')) // Ok in types, no throw
Enter fullscreen mode Exit fullscreen mode

Fixed inspection output results for Result and Option in Node.js.

Release notes: https://github.com/vitalics/rslike/releases/tag/%40rslike%2Fstd%403.1.0
Link to the project: https://github.com/vitalics/rslike/tree/main/packages/std

Top comments (0)