Releases: erikjuhani/fp-utils
0.16.0
Full Changelog: 0.15.0...0.16.0
Breaking changes
Change type guards to return never instead of false
Previously when invoking the isOk
on Err type or isErr
on Ok type
would return always false and the corresponding type would be set as the
original type. This however does not work with the newest TypeScript
version 5.5.3
. The failure in this case is correct as the inference
does not work as expected if a false is returned instead of a type
guard.
The 'correct' change here is to instead return never type guard as we
can never enter that block that checks for isErr or isOk on a type that
does not reflect it.
Example:
const ok = Ok(42);
// Previously this was accepted and the type was inferred as Ok in the
// code block
if (ok.isErr()) {
ok;
// ^? Ok<number>;
}
// However now the type would be never, which is less flexible, but
// correct behaviour
if (ok.isErr()) {
ok;
// ^? never
}
Change type guards to return never instead of false in option
Previously when invoking the isSome
on None type or isNone
on Some
type would return always false and the corresponding type would be set
as the original type. This however does not work with the newest
TypeScript version 5.5.3
. The failure in this case is correct as the
inference does not work as expected if a false is returned instead of a
type guard.
The 'correct' change here is to instead return never type guard as we
can never enter that block that checks for isNone or isSome on a type
that does not reflect it.
Example:
const some = Some(42);
// Previously this was accepted and the type was inferred as Some in the
// code block
if (some.isNone()) {
some;
// ^? Some<number>;
}
// However now the type would be never, which is less flexible, but
// correct behaviour
if (some.isNone()) {
some;
// ^? never
}
Changes
Add terser to minify code published to npm
Terser is a JavaScript mangler/compressor. More info here:
https://github.com/terser/terser
By utilizing terser the size of the output distribution files is
considerable smaller as the code is compressed and mangled to minimum
functional state. Terser also removes comments, which in turn replaces
the naive comment remove solution that was relying on regex.
The compressed output file size is around 50% smaller from 4.33kb to
2.2kb for option module.
Fixes
Fix details tags in Option and Result README
Some of the details tags were missing ending tag counterpart.
0.15.0
Full Changelog: 0.14.0...0.15.0
Breaking changes
Add Option.toJSON method and static variant
Option.toJSON serializes the option into JSON format. If the option is
None, it will be serialized to null
. If the option is Some, it will be
serialized to the unwrapped value T
.
This function acts as the interoperability layer between Option type and
TypeScript. For example nullish coalescing can be utilized with this
function.
// Nullish coalescing
const option: Option<string> = None;
const result = option.toJSON() ?? "defaultValue";
// Optional chaining
const option: Option<{ name: string }> = None;
const result = option.toJSON()?.name;
Add Result.toJSON method and static variant
Result.toJSON serializes the result into JSON format. An Ok value will
be serialized to { "ok": T }
, and an Err value will be serialized to
{ "err": TError }
.
This function acts as the interoperability layer between Result type and
TypeScript.
0.14.0
Full Changelog: 0.13.1...0.14.0
Breaking changes
The target change affects both Result and Option modules.
Change build_npm target to ES2022 to support cause property
Error cause
property is supported from "ES2022" onwards.
Changes
Add cause property when throwing with expect on Err type
This will help to identify the originating error with stacktrace and
orginal error message, otherwise the original error would be lost.
Features
Add Option.all and Option.any static methods
Option.all returns all Some option values as an array within a Some
option. If None option exists in the array, None is returned. An empty
array signifies success, resulting in a Some with an empty array.
Option.any returns the first Some option encountered. If no Some options
are found in the array None is returned.
Add Result.all and Result.any static methods
Result.all returns all Ok result values as an array within an Ok result
if no Err results are present. If any Err result exists in the array,
the first one is returned. An empty array signifies success, resulting
in an Ok with an empty array.
Result.any returns the first Ok result encountered. If no Ok results are
found in the array, all Err result values are returned as an array
within an Err result.
0.13.1
Full Changelog: 0.13.0...0.13.1
Features
Add Option.toString method and higher-order function variant
Signature: (): "Some(value)" | "None"
Option.toString returns the string representation of the option and the
stringified value as Some(value)
if the result is Some
or None
if
the result is None
.
Some(42)
.toString(); // Evaluates to "Some(42)"
None
.toString(); // Evaluates to "None"
Custom inspect symbol was "Deno.customInspect"
introduced to the
Option classes Some
and None
to produce more formatted and readable
output for option values using the Option.toString method. For example,
calling console.log(Some(42));
will now print Some(42)
, whereas
previously, it would have been printed as Some {}.
Add Result.toString method and higher-order function variant
Signature: (): "Ok(value)" | "Err(value)"
Result.toString returns the string representation of the result and the
stringified value as Ok(value)
if the result is Ok
or Err(value)
if the result is Err
.
Ok(42)
.toString(); // Evaluates to "Ok(42)"
Err(42)
.toString(); // Evaluates to "Err(42)"
Custom inspect symbol was "Deno.customInspect"
introduced to the
Result classes Ok
and Err
to produce more formatted and readable
output for result values using the Result.toString method. For example,
calling console.log(Ok(42));
will now print Ok(42)
, whereas
previously, it would have been printed as Ok {}.
Add Result.partition static method
Result.partition unwraps an array of results into a tuple of unwrapped
Ok and Err values. This is especially useful if for example all errors
and success cases need to be evaluated individually.
0.13.0
Full Changelog: 0.12.0...0.13.0
Features
Add Option.zip method and higher-order function variant
Signature: <U>(option: Option<U>): Option<[T, U]>
Option.zip combines two option values into a tuple and returns the tuple
wrapped in Option.
Some(42).zip(Some(84)); // Evaluates to Some<[42, 84]>
Some(42).zip(None); // Evaluates to None
None.zip(Some(84)); // Evaluates to None
Fixes
Fix expectErr code examples in Result module README
Fix type inference for unwrap, unwrapErr, isOk and isErr HOFs
These functions were still missing the previous fixes that were
introduced in eef0502.
Add type inference tests for these higher-order functions.
Changes
Improve type inference for result higher order functions
Add better type inference for Result methods by using a generic result
type TResult extends Result<unknown, unknown>
and infer keyword to get
the inner value type of the result TResult extends Result<infer U, infer _> ? U : never
.
Fixes flatMap type inference when performing flatMap on Err type.
Previously the Err type flatMap would be inferred from the given
function return Result, which could be completely wrong as the result
inner value types can be changed. Now properly takes the parent type
into account if the Err inner type changes in the flatMap function. This
will now be properly inferred into the returned result type
Result<U, TError | UError>
. If the Err type cannot be inferred from
the parent type–unknown will be returned instead. This is better than
having wrong error type returned.
Make union result type tests more complicated to test more type
inference cases. Also adds more type tests for Result type higher order
functions.
Improve type inference for Option flatMap
Improve type inference for Option higher order functions
Add better type inference for Option methods by using a generic option
type TOption extends Option<any>
and infer keyword to get the inner
value type of the Option TOption extends Option<infer U> ? U : never
.
If the Option type cannot be inferred from the parent type unknown will
be returned instead. This is better than having wrong Option type
returned.
Make union Option type tests more complicated to test more type
inference cases. Also adds more type tests for Option type higher order
functions.
The method isSome
returns false when called from a None value and the
method isNone
return false when called from a Some value.
0.12.0
Full Changelog: 0.11.1...0.12.0
Features
Add expect and expectErr for Result
Result.expect will return the wrapped value if the result is Ok. If the result is Err, the function will throw an error with the given input
value as the error message. Similarly, Result.expectErr will return the wrapped value if the result is Err, and throw an error if the result is Ok.
Fixes
Fix imports in Result module documentation code example
Changes
Improve constructor documentation
The examples in constructor functiosn Some, Ok and Err are now properly displayed. Previously the language server information would show the static method Result.ok
or Option.some
examples.
Improve Result isOk and isErr type guard type inference
Improve Option isSome and isNone type guard type inference
0.11.1
Full Changelog: 0.11.0...0.11.1
Fixes
Fixes bloated npm distributions due to not stripping comments from js files.
Strip comments from option.js and result.js files
After refactoring most of the functionality under option.js and
result.js files the comments were left in resulting in a bloated
distribution.
This changes the behavior to also account for result.js and option.js
files and not just the mod.js files.
0.11.0
Full Changelog: 0.10.0...0.11.0
Breaking Changes
Option module overhaul
First the big change for the API! Previously users needed to create Some
type and None type through the namespace function .some
or .none
respectively. This felt a bit tedious at times as calling
Option.some(42)
is quite verbose. In this overhaul Some()
and
None()
functions were introduced. These are actually behind a Proxy
that will apply the arguments to the class constructors. None being a
static entity. To achieve the API we use a Proxy to trap the function
call and then return the constructed entity. The static functions are
still kept for more concise operability with callbacks and to retain
backwards compatibility. The breaking change is when callers need to
type with either Option.Some or Option.None. These will now result in
compiler error and should be changed to just Some or None.
Other big change introduced in this commit was the use of abstract class
and static methods for the Option type. This allows for better
interoperability and for example the documentation can now be written
only for the abstract methods and these will still be visible from the
Some and None classes.
README was also updated to encompass these changes. Static methods and
higher-order functions were documented in the README usage section as
well.
Tests and examples were updated to match the new API.
Result module overhaul
First the big change for the API! Previously users needed to create Ok
and Err types through the namespace function .ok
or .err
respectively. This felt a bit tedious at times as calling
Result.ok(42)
is quite verbose. In this overhaul Ok()
and Err()
functions were introduced. These are actually just the same static
methods as previously, but acting as constructor functions similar to
JavaScript String
and Number
constructors. The static functions are
still kept for more concise operability with callbacks and to retain
backwards compatibility. The breaking change is when callers have types
Result.Ok or Result.Err. After these changes these types will now result
in compiler error and should be changed to Ok or Err instead.
Other big change introduced in this commit was the use of abstract class
and static methods for the Result type. This allows for better
interoperability and for example the documentation can now be written
only for the abstract methods and these will be inherited by extending
and appear visible from the Ok and Err class methods.
README was also updated to encompass these changes. Static methods,
constructor functions and higher-order functions are documented in the
README usage section.
Tests and examples were updated to match the new API.
0.10.0
Full Changelog: 0.9.0...0.10.0
Features
Add Option.filter function to filter options
Option.filter returns a boolean that is evaluated with the given predicate
function which is applied on the option value T
. None evaluates to false
.
Add Result.filter function to filter results
Result.filter returns a boolean that is evaluated with the given predicate
function which is applied on the result value T
. Err evaluates to false
.
Support promise likes with Option.from and Result.from functions
Essentially this means that using custom PromiseLike objects is now safe. All PromiseLikes (including regular promises) are wrapped in Promise.resolve call. Promise.resolve will flatten any promises or promise likes and also reject if any underlying promise like is rejected.
Changes
Better type inference for union types with Option.match
The higher order function Option.match would break when given union type of Options. This was fixed by making the Option a generic in the function. The generic is then inferred explicitly for the some callback.
Better type inference for union types with Result.match
The higher order function Result.match would break when given union type of Results. This was fixed by making the Result a generic in the function TResult
. The generic inner value is then inferred explicitly for the callbacks.
Change Result.from to error map function as the second argument
This enables better handling of the underlying exception. The value parameter needs to be typed by the caller otherwise it will be inferred as unknown. This is not type-safe as catched errors are not typed.
Fixes
Fix Option.match and Result.match generic could be any type
Now the generic type is correctly enforced to be either Option or Result.
0.9.0
Full Changelog: 0.8.0...0.9.0
BREAKING CHANGES:
Use undefined instead of void as the unit type for Result
Reason for this is that the void
type and undefined
type behave
differently. undefined
is actually the correct type to use here as the
unit type as void
type is explicitly used for functions that return
nothing. In runtime void type is undefined.
Type inference behaves differently with undefined and void types.
Undefined is more lenient and works better when performing type
inference.
CHANGES:
Improve return type correctness for Option.from function
Previously the from function could return also Some explicitly, this was
changed to always return Option or None in obvious cases. A never
type is returned if T extends undefined
, which means that we return a
"None" type from the function. In this case we skip the explicit None
type in the return type and only return type Option, which implicitly
includes a None type.
Make the value in Some explicitly of type NonNullable
This prevents giving nullable values for some to an extent, if that check is skipped then Some constructor will throw in runtime.
Improve type inference for Option type
Add option_test_types.ts
for testing type inference for Option module.
These type inference improvements were derived from the new type
inference testing file which checks that the input and return types are
as expected.
This test failed for flatMap and inspect functions, which required some
changes to them. Type assertion was used to solve the inference problems
in both of these higher order functions.
Improve type inference for Result type
Add result_test_types.ts
for testing type inference for Result module.