happy-rusty 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,11 @@ pub enum Option<T> {
33
33
  export interface Option<T> {
34
34
  // #region Internal properties
35
35
 
36
+ /**
37
+ * [object Option].
38
+ */
39
+ [Symbol.toStringTag]: 'Option',
40
+
36
41
  /**
37
42
  * Identify `Some` or `None`.
38
43
  *
@@ -277,6 +282,11 @@ export interface Option<T> {
277
282
  eq(other: Option<T>): boolean;
278
283
 
279
284
  // #endregion
285
+
286
+ /**
287
+ * Custom `toString` implementation that uses the `Option`'s contained value.
288
+ */
289
+ toString(): string;
280
290
  }
281
291
 
282
292
  /**
@@ -330,6 +340,11 @@ pub enum Result<T, E> {
330
340
  export interface Result<T, E> {
331
341
  // #region Internal properties
332
342
 
343
+ /**
344
+ * [object Result].
345
+ */
346
+ [Symbol.toStringTag]: 'Result',
347
+
333
348
  /**
334
349
  * Identify `Ok` or `Err`.
335
350
  *
@@ -567,6 +582,32 @@ export interface Result<T, E> {
567
582
  eq(other: Result<T, E>): boolean;
568
583
 
569
584
  // #endregion
585
+
586
+ /**
587
+ * Transforms the current Result into a new Result where the type of the error result is replaced with a new type `F`.
588
+ * The type of the success result remains unchanged.
589
+ * Just same as `result as unknown as Result<T, F>`.
590
+ *
591
+ * @typeParam F - The new type for the error result.
592
+ * @returns `this` but the error result type is `F`.
593
+ */
594
+ asOk<F>(): Result<T, F>;
595
+
596
+ /**
597
+ * Transforms the current Result into a new Result where the type of the success result is replaced with a new type `U`.
598
+ * The type of the error result remains unchanged.
599
+ * Useful where you need to return an Error chained to another type.
600
+ * Just same as `result as unknown as Result<U, E>`.
601
+ *
602
+ * @typeParam U - The new type for the success result.
603
+ * @returns `this` but the success result type is `U`.
604
+ */
605
+ asErr<U>(): Result<U, E>;
606
+
607
+ /**
608
+ * Custom `toString` implementation that uses the `Result`'s contained value.
609
+ */
610
+ toString(): string;
570
611
  }
571
612
 
572
613
  /**
@@ -624,45 +665,72 @@ export type AsyncIOResult<T> = Promise<IOResult<T>>;
624
665
  */
625
666
  export function Some<T>(value: T): Option<T> {
626
667
  const some: Option<T> = {
668
+ [Symbol.toStringTag]: 'Option',
627
669
  [optionKindSymbol]: 'Some',
628
670
 
629
- isSome: (): true => true,
630
- isNone: (): false => false,
631
- isSomeAnd: (predicate: (value: T) => boolean): boolean => predicate(value),
671
+ isSome(): true {
672
+ return true;
673
+ },
674
+ isNone(): false {
675
+ return false;
676
+ },
677
+ isSomeAnd(predicate: (value: T) => boolean): boolean {
678
+ return predicate(value);
679
+ },
632
680
 
633
- expect: (_msg: string): T => value,
634
- unwrap: (): T => value,
635
- unwrapOr: (_defaultValue: T): T => value,
636
- unwrapOrElse: (_fn: () => T): T => value,
681
+ expect(_msg: string): T {
682
+ return value;
683
+ },
684
+ unwrap(): T {
685
+ return value;
686
+ },
687
+ unwrapOr(_defaultValue: T): T {
688
+ return value;
689
+ },
690
+ unwrapOrElse(_fn: () => T): T {
691
+ return value;
692
+ },
637
693
 
638
- okOr: <E>(_error: E): Result<T, E> => Ok(value),
639
- okOrElse: <E>(_err: () => E): Result<T, E> => Ok(value),
640
- transpose: <T, E>(): Result<Option<T>, E> => {
694
+ okOr<E>(_error: E): Result<T, E> {
695
+ return Ok(value);
696
+ },
697
+ okOrElse<E>(_err: () => E): Result<T, E> {
698
+ return Ok(value);
699
+ },
700
+ transpose<T, E>(): Result<Option<T>, E> {
641
701
  const r = value as unknown as Result<T, E>;
642
702
  assertResult(r);
643
703
  return r.isOk() ? Ok(Some(r.unwrap())) : Err(r.unwrapErr());
644
704
  },
645
705
 
646
- filter: (predicate: (value: T) => boolean): Option<T> => predicate(value) ? some : None,
647
- flatten: <T>(): Option<T> => {
706
+ filter(predicate: (value: T) => boolean): Option<T> {
707
+ return predicate(value) ? some : None;
708
+ },
709
+ flatten<T>(): Option<T> {
648
710
  const o = value as unknown as Option<T>;
649
711
  assertOption(o);
650
712
  return o;
651
713
  },
652
- map: <U>(fn: (value: T) => U): Option<U> => Some(fn(value)),
714
+ map<U>(fn: (value: T) => U): Option<U> {
715
+ return Some(fn(value));
716
+ },
653
717
 
654
- mapOr: <U>(_defaultValue: U, fn: (value: T) => U): U => fn(value),
655
- mapOrElse: <U>(_defaultFn: () => U, fn: (value: T) => U): U => fn(value),
718
+ mapOr<U>(_defaultValue: U, fn: (value: T) => U): U {
719
+ return fn(value);
720
+ },
721
+ mapOrElse<U>(_defaultFn: () => U, fn: (value: T) => U): U {
722
+ return fn(value);
723
+ },
656
724
 
657
- zip: <U>(other: Option<U>): Option<[T, U]> => {
725
+ zip<U>(other: Option<U>): Option<[T, U]> {
658
726
  assertOption(other);
659
727
  return other.isSome() ? Some([value, other.unwrap()]) : None;
660
728
  },
661
- zipWith: <U, R>(other: Option<U>, fn: (value: T, otherValue: U) => R): Option<R> => {
729
+ zipWith<U, R>(other: Option<U>, fn: (value: T, otherValue: U) => R): Option<R> {
662
730
  assertOption(other);
663
731
  return other.isSome() ? Some(fn(value, other.unwrap())) : None;
664
732
  },
665
- unzip: <T, U>(): [Option<T>, Option<U>] => {
733
+ unzip<T, U>(): [Option<T>, Option<U>] {
666
734
  const tuple = value as unknown as [T, U];
667
735
 
668
736
  if (!Array.isArray(tuple) || tuple.length !== 2) {
@@ -673,27 +741,37 @@ export function Some<T>(value: T): Option<T> {
673
741
  return [Some(a), Some(b)];
674
742
  },
675
743
 
676
- and: <U>(other: Option<U>): Option<U> => {
744
+ and<U>(other: Option<U>): Option<U> {
677
745
  assertOption(other);
678
746
  return other;
679
747
  },
680
- andThen: <U>(fn: (value: T) => Option<U>): Option<U> => fn(value),
681
- or: (_other: Option<T>): Option<T> => some,
682
- orElse: (_fn: () => Option<T>): Option<T> => some,
683
- xor: (other: Option<T>): Option<T> => {
748
+ andThen<U>(fn: (value: T) => Option<U>): Option<U> {
749
+ return fn(value);
750
+ },
751
+ or(_other: Option<T>): Option<T> {
752
+ return some;
753
+ },
754
+ orElse(_fn: () => Option<T>): Option<T> {
755
+ return some;
756
+ },
757
+ xor(other: Option<T>): Option<T> {
684
758
  assertOption(other);
685
759
  return other.isSome() ? None : some;
686
760
  },
687
761
 
688
- inspect: (fn: (value: T) => void): Option<T> => {
762
+ inspect(fn: (value: T) => void): Option<T> {
689
763
  fn(value);
690
764
  return some;
691
765
  },
692
766
 
693
- eq: (other: Option<T>): boolean => {
767
+ eq(other: Option<T>): boolean {
694
768
  assertOption(other);
695
769
  return other.isSome() && other.unwrap() === value;
696
770
  },
771
+
772
+ toString(): string {
773
+ return `Some(${ value })`;
774
+ },
697
775
  } as const;
698
776
 
699
777
  return some;
@@ -704,54 +782,99 @@ export function Some<T>(value: T): Option<T> {
704
782
  * This constant is frozen to ensure it is immutable and cannot be altered, preserving the integrity of `None` throughout the application.
705
783
  */
706
784
  export const None = Object.freeze<None>({
785
+ [Symbol.toStringTag]: 'Option',
707
786
  [optionKindSymbol]: 'None',
708
787
 
709
- isSome: (): false => false,
710
- isNone: (): true => true,
711
- isSomeAnd: (_predicate: (value: never) => boolean): false => false,
788
+ isSome(): false {
789
+ return false;
790
+ },
791
+ isNone(): true {
792
+ return true;
793
+ },
794
+ isSomeAnd(_predicate: (value: never) => boolean): false {
795
+ return false;
796
+ },
712
797
 
713
- expect: (msg: string): never => {
798
+ expect(msg: string): never {
714
799
  throw new TypeError(msg);
715
800
  },
716
- unwrap: (): never => {
801
+ unwrap(): never {
717
802
  throw new TypeError('Called `Option::unwrap()` on a `None` value');
718
803
  },
719
- unwrapOr: <T>(defaultValue: T): T => defaultValue,
720
- unwrapOrElse: <T>(fn: () => T): T => fn(),
804
+ unwrapOr<T>(defaultValue: T): T {
805
+ return defaultValue;
806
+ },
807
+ unwrapOrElse<T>(fn: () => T): T {
808
+ return fn();
809
+ },
721
810
 
722
- okOr: <E>(error: E): Result<never, E> => Err(error),
723
- okOrElse: <E>(err: () => E): Result<never, E> => Err(err()),
724
- transpose: (): Result<None, never> => Ok(None),
811
+ okOr<E>(error: E): Result<never, E> {
812
+ return Err(error);
813
+ },
814
+ okOrElse<E>(err: () => E): Result<never, E> {
815
+ return Err(err());
816
+ },
817
+ transpose(): Result<None, never> {
818
+ return Ok(None);
819
+ },
725
820
 
726
- filter: (_predicate: (value: never) => boolean): None => None,
727
- flatten: (): None => None,
728
- map: <U>(_fn: (value: never) => U): None => None,
821
+ filter(_predicate: (value: never) => boolean): None {
822
+ return None;
823
+ },
824
+ flatten(): None {
825
+ return None;
826
+ },
827
+ map<U>(_fn: (value: never) => U): None {
828
+ return None;
829
+ },
729
830
 
730
- mapOr: <U>(defaultValue: U, _fn: (value: never) => U): U => defaultValue,
731
- mapOrElse: <U>(defaultFn: () => U, _fn: (value: never) => U): U => defaultFn(),
831
+ mapOr<U>(defaultValue: U, _fn: (value: never) => U): U {
832
+ return defaultValue;
833
+ },
834
+ mapOrElse<U>(defaultFn: () => U, _fn: (value: never) => U): U {
835
+ return defaultFn();
836
+ },
732
837
 
733
- zip: <U>(_other: Option<U>): None => None,
734
- zipWith: <U, R>(_other: Option<U>, _fn: (value: never, otherValue: U) => R): None => None,
735
- unzip: (): [None, None] => [None, None],
838
+ zip<U>(_other: Option<U>): None {
839
+ return None;
840
+ },
841
+ zipWith<U, R>(_other: Option<U>, _fn: (value: never, otherValue: U) => R): None {
842
+ return None;
843
+ },
844
+ unzip(): [None, None] {
845
+ return [None, None];
846
+ },
736
847
 
737
- and: <U>(_other: Option<U>): None => None,
738
- andThen: <U>(_fn: (value: never) => Option<U>): None => None,
739
- or: <T>(other: Option<T>): Option<T> => {
848
+ and<U>(_other: Option<U>): None {
849
+ return None;
850
+ },
851
+ andThen<U>(_fn: (value: never) => Option<U>): None {
852
+ return None;
853
+ },
854
+ or<T>(other: Option<T>): Option<T> {
740
855
  assertOption(other);
741
856
  return other;
742
857
  },
743
- orElse: <T>(fn: () => Option<T>): Option<T> => fn(),
744
- xor: <T>(other: Option<T>): Option<T> => {
858
+ orElse<T>(fn: () => Option<T>): Option<T> {
859
+ return fn();
860
+ },
861
+ xor<T>(other: Option<T>): Option<T> {
745
862
  assertOption(other);
746
863
  return other.isSome() ? other : None;
747
864
  },
748
865
 
749
- inspect: (_fn: (value: never) => void): None => None,
866
+ inspect(_fn: (value: never) => void): None {
867
+ return None;
868
+ },
750
869
 
751
- eq: <T>(other: Option<T>): boolean => {
870
+ eq<T>(other: Option<T>): boolean {
752
871
  assertOption(other);
753
872
  return other === None;
754
873
  },
874
+
875
+ toString(): string {
876
+ return 'None';
877
+ },
755
878
  }) as None;
756
879
 
757
880
  /**
@@ -773,61 +896,109 @@ export const None = Object.freeze<None>({
773
896
  */
774
897
  export function Ok<T, E>(value: T): Result<T, E> {
775
898
  const ok: Result<T, E> = {
899
+ [Symbol.toStringTag]: 'Result',
776
900
  [resultKindSymbol]: 'Ok',
777
901
 
778
- isOk: (): true => true,
779
- isErr: (): false => false,
780
- isOkAnd: (predicate: (value: T) => boolean): boolean => predicate(value),
781
- isErrAnd: (_predicate: (error: E) => boolean): false => false,
902
+ isOk(): true {
903
+ return true;
904
+ },
905
+ isErr(): false {
906
+ return false;
907
+ },
908
+ isOkAnd(predicate: (value: T) => boolean): boolean {
909
+ return predicate(value);
910
+ },
911
+ isErrAnd(_predicate: (error: E) => boolean): false {
912
+ return false;
913
+ },
782
914
 
783
- expect: (_msg: string): T => value,
784
- unwrap: (): T => value,
785
- unwrapOr: (_defaultValue: T): T => value,
786
- unwrapOrElse: (_fn: (error: E) => T): T => value,
915
+ expect(_msg: string): T {
916
+ return value;
917
+ },
918
+ unwrap(): T {
919
+ return value;
920
+ },
921
+ unwrapOr(_defaultValue: T): T {
922
+ return value;
923
+ },
924
+ unwrapOrElse(_fn: (error: E) => T): T {
925
+ return value;
926
+ },
787
927
 
788
- expectErr: (msg: string): E => {
928
+ expectErr(msg: string): E {
789
929
  throw new TypeError(`${ msg }: ${ value }`);
790
930
  },
791
- unwrapErr: (): E => {
931
+ unwrapErr(): E {
792
932
  throw new TypeError('Called `Result::unwrapErr()` on an `Ok` value');
793
933
  },
794
934
 
795
- ok: (): Option<T> => Some(value),
796
- err: (): None => None,
797
- transpose: <T>(): Option<Result<T, E>> => {
935
+ ok(): Option<T> {
936
+ return Some(value);
937
+ },
938
+ err(): None {
939
+ return None;
940
+ },
941
+ transpose<T>(): Option<Result<T, E>> {
798
942
  const o = value as Option<T>;
799
943
  assertOption(o);
800
944
  return o.isSome() ? Some(Ok(o.unwrap())) : None;
801
945
  },
802
946
 
803
- map: <U>(fn: (value: T) => U): Result<U, E> => Ok(fn(value)),
804
- mapErr: <F>(_fn: (error: E) => F): Result<T, F> => Ok(value),
805
- mapOr: <U>(_defaultValue: U, fn: (value: T) => U): U => fn(value),
806
- mapOrElse: <U>(_defaultFn: (error: E) => U, fn: (value: T) => U): U => fn(value),
807
- flatten: <T>(): Result<T, E> => {
947
+ map<U>(fn: (value: T) => U): Result<U, E> {
948
+ return Ok(fn(value));
949
+ },
950
+ mapErr<F>(_fn: (error: E) => F): Result<T, F> {
951
+ return Ok(value);
952
+ },
953
+ mapOr<U>(_defaultValue: U, fn: (value: T) => U): U {
954
+ return fn(value);
955
+ },
956
+ mapOrElse<U>(_defaultFn: (error: E) => U, fn: (value: T) => U): U {
957
+ return fn(value);
958
+ },
959
+ flatten<T>(): Result<T, E> {
808
960
  const r = value as Result<T, E>;
809
961
  assertResult(r);
810
962
  return r;
811
963
  },
812
964
 
813
- and: <U>(other: Result<U, E>): Result<U, E> => {
965
+ and<U>(other: Result<U, E>): Result<U, E> {
814
966
  assertResult(other);
815
967
  return other;
816
968
  },
817
- or: <F>(_other: Result<T, F>): Result<T, F> => ok as unknown as Result<T, F>,
818
- andThen: <U>(fn: (value: T) => Result<U, E>): Result<U, E> => fn(value),
819
- orElse: <F>(_fn: (error: E) => Result<T, F>): Result<T, F> => ok as unknown as Result<T, F>,
969
+ or<F>(_other: Result<T, F>): Result<T, F> {
970
+ return ok as unknown as Result<T, F>;
971
+ },
972
+ andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E> {
973
+ return fn(value);
974
+ },
975
+ orElse<F>(_fn: (error: E) => Result<T, F>): Result<T, F> {
976
+ return ok as unknown as Result<T, F>;
977
+ },
820
978
 
821
- inspect: (fn: (value: T) => void): Result<T, E> => {
979
+ inspect(fn: (value: T) => void): Result<T, E> {
822
980
  fn(value);
823
981
  return ok;
824
982
  },
825
- inspectErr: (_fn: (error: E) => void): Result<T, E> => ok,
983
+ inspectErr(_fn: (error: E) => void): Result<T, E> {
984
+ return ok;
985
+ },
826
986
 
827
- eq: (other: Result<T, E>): boolean => {
987
+ eq(other: Result<T, E>): boolean {
828
988
  assertResult(other);
829
989
  return other.isOk() && other.unwrap() === value;
830
990
  },
991
+
992
+ asOk<F>(): Result<T, F> {
993
+ return ok as unknown as Result<T, F>;
994
+ },
995
+ asErr(): never {
996
+ throw new TypeError('Called `Result::asErr()` on an `Ok` value');
997
+ },
998
+
999
+ toString(): string {
1000
+ return `Ok(${ value })`;
1001
+ },
831
1002
  } as const;
832
1003
 
833
1004
  return ok;
@@ -852,53 +1023,105 @@ export function Ok<T, E>(value: T): Result<T, E> {
852
1023
  */
853
1024
  export function Err<T, E>(error: E): Result<T, E> {
854
1025
  const err: Result<T, E> = {
1026
+ [Symbol.toStringTag]: 'Result',
855
1027
  [resultKindSymbol]: 'Err',
856
1028
 
857
- isOk: (): false => false,
858
- isErr: (): true => true,
859
- isOkAnd: (_predicate: (value: T) => boolean): false => false,
860
- isErrAnd: (predicate: (error: E) => boolean): boolean => predicate(error),
1029
+ isOk(): false {
1030
+ return false;
1031
+ },
1032
+ isErr(): true {
1033
+ return true;
1034
+ },
1035
+ isOkAnd(_predicate: (value: T) => boolean): false {
1036
+ return false;
1037
+ },
1038
+ isErrAnd(predicate: (error: E) => boolean): boolean {
1039
+ return predicate(error);
1040
+ },
861
1041
 
862
- expect: (msg: string): T => {
1042
+ expect(msg: string): T {
863
1043
  throw new TypeError(`${ msg }: ${ error }`);
864
1044
  },
865
- unwrap: (): T => {
1045
+ unwrap(): T {
866
1046
  throw new TypeError('Called `Result::unwrap()` on an `Err` value');
867
1047
  },
868
- unwrapOr: (defaultValue: T): T => defaultValue,
869
- unwrapOrElse: (fn: (error: E) => T): T => fn(error),
1048
+ unwrapOr(defaultValue: T): T {
1049
+ return defaultValue;
1050
+ },
1051
+ unwrapOrElse(fn: (error: E) => T): T {
1052
+ return fn(error);
1053
+ },
870
1054
 
871
- expectErr: (_msg: string): E => error,
872
- unwrapErr: (): E => error,
1055
+ expectErr(_msg: string): E {
1056
+ return error;
1057
+ },
1058
+ unwrapErr(): E {
1059
+ return error;
1060
+ },
873
1061
 
874
- ok: (): None => None,
875
- err: (): Option<E> => Some(error),
876
- transpose: <T>(): Option<Result<T, E>> => Some(err as unknown as Result<T, E>),
1062
+ ok(): None {
1063
+ return None;
1064
+ },
1065
+ err(): Option<E> {
1066
+ return Some(error);
1067
+ },
1068
+ transpose<T>(): Option<Result<T, E>> {
1069
+ return Some(err as unknown as Result<T, E>);
1070
+ },
877
1071
 
878
- map: <U>(_fn: (value: T) => U): Result<U, E> => err as unknown as Result<U, E>,
879
- mapErr: <F>(fn: (error: E) => F): Result<T, F> => Err(fn(error)),
880
- mapOr: <U>(defaultValue: U, _fn: (value: T) => U): U => defaultValue,
881
- mapOrElse: <U>(defaultFn: (error: E) => U, _fn: (value: T) => U): U => defaultFn(error),
882
- flatten: <T>(): Result<T, E> => err as unknown as Result<T, E>,
1072
+ map<U>(_fn: (value: T) => U): Result<U, E> {
1073
+ return err as unknown as Result<U, E>;
1074
+ },
1075
+ mapErr<F>(fn: (error: E) => F): Result<T, F> {
1076
+ return Err(fn(error));
1077
+ },
1078
+ mapOr<U>(defaultValue: U, _fn: (value: T) => U): U {
1079
+ return defaultValue;
1080
+ },
1081
+ mapOrElse<U>(defaultFn: (error: E) => U, _fn: (value: T) => U): U {
1082
+ return defaultFn(error);
1083
+ },
1084
+ flatten<T>(): Result<T, E> {
1085
+ return err as unknown as Result<T, E>;
1086
+ },
883
1087
 
884
- and: <U>(_other: Result<U, E>): Result<U, E> => err as unknown as Result<U, E>,
885
- or: <F>(other: Result<T, F>): Result<T, F> => {
1088
+ and<U>(_other: Result<U, E>): Result<U, E> {
1089
+ return err as unknown as Result<U, E>;
1090
+ },
1091
+ or<F>(other: Result<T, F>): Result<T, F> {
886
1092
  assertResult(other);
887
1093
  return other;
888
1094
  },
889
- andThen: <U>(_fn: (value: T) => Result<U, E>): Result<U, E> => err as unknown as Result<U, E>,
890
- orElse: <F>(fn: (error: E) => Result<T, F>): Result<T, F> => fn(error),
1095
+ andThen<U>(_fn: (value: T) => Result<U, E>): Result<U, E> {
1096
+ return err as unknown as Result<U, E>;
1097
+ },
1098
+ orElse<F>(fn: (error: E) => Result<T, F>): Result<T, F> {
1099
+ return fn(error);
1100
+ },
891
1101
 
892
- inspect: (_fn: (value: T) => void): Result<T, E> => err,
893
- inspectErr: (fn: (error: E) => void): Result<T, E> => {
1102
+ inspect(_fn: (value: T) => void): Result<T, E> {
1103
+ return err;
1104
+ },
1105
+ inspectErr(fn: (error: E) => void): Result<T, E> {
894
1106
  fn(error);
895
1107
  return err;
896
1108
  },
897
1109
 
898
- eq: (other: Result<T, E>): boolean => {
1110
+ eq(other: Result<T, E>): boolean {
899
1111
  assertResult(other);
900
1112
  return other.isErr() && other.unwrapErr() === error;
901
1113
  },
1114
+
1115
+ asOk(): never {
1116
+ throw new TypeError('Called `Result::asOk()` on an `Err` value');
1117
+ },
1118
+ asErr<U>(): Result<U, E> {
1119
+ return err as unknown as Result<U, E>;
1120
+ },
1121
+
1122
+ toString(): string {
1123
+ return `Err(${ error })`;
1124
+ },
902
1125
  } as const;
903
1126
 
904
1127
  return err;
@@ -912,8 +1135,7 @@ export function Err<T, E>(error: E): Result<T, E> {
912
1135
  * @throws {TypeError} If the value is not an `Option`.
913
1136
  */
914
1137
  function assertOption<T>(o: Option<T>): void {
915
- // `Some` and `None` must be an object.
916
- if (o == null || typeof o !== 'object' || !(optionKindSymbol in o)) {
1138
+ if (!isOption(o)) {
917
1139
  throw new TypeError(`This(${ o }) is not an Option`);
918
1140
  }
919
1141
  }
@@ -927,8 +1149,7 @@ function assertOption<T>(o: Option<T>): void {
927
1149
  * @throws {TypeError} If the value is not a `Result`.
928
1150
  */
929
1151
  function assertResult<T, E>(r: Result<T, E>): void {
930
- // `Ok` and `Err` must be an object.
931
- if (r == null || typeof r !== 'object' || !(resultKindSymbol in r)) {
1152
+ if (!isResult(r)) {
932
1153
  throw new TypeError(`This(${ r }) is not a Result`);
933
1154
  }
934
1155
  }
@@ -960,4 +1181,29 @@ export function promiseToResult<T, E = Error>(p: Promise<T>): Promise<Result<T,
960
1181
  }).catch((err: E): Result<T, E> => {
961
1182
  return Err(err);
962
1183
  });
1184
+ }
1185
+
1186
+ /**
1187
+ * Checks if a value is an `Option`.
1188
+ *
1189
+ * @typeParam T - The expected type of the value contained within the `Option`.
1190
+ * @param o - The value to be checked as an `Option`.
1191
+ * @returns `true` if the value is an `Option`, otherwise `false`.
1192
+ */
1193
+ export function isOption<T>(o: unknown): o is Option<T> {
1194
+ // `Some` and `None` must be an object.
1195
+ return o != null && typeof o === 'object' && optionKindSymbol in o;
1196
+ }
1197
+
1198
+ /**
1199
+ * Checks if a value is a `Result`.
1200
+ *
1201
+ * @typeParam T - The expected type of the success value contained within the `Result`.
1202
+ * @typeParam E - The expected type of the error value contained within the `Result`.
1203
+ * @param r - The value to be checked as a `Result`.
1204
+ * @returns `true` if the value is a `Result`, otherwise `false`.
1205
+ */
1206
+ export function isResult<T, E>(r: unknown): r is Result<T, E> {
1207
+ // `Ok` and `Err` must be an object.
1208
+ return r != null && typeof r === 'object' && resultKindSymbol in r;
963
1209
  }
package/src/mod.ts CHANGED
@@ -3,6 +3,8 @@ export {
3
3
  None,
4
4
  Ok,
5
5
  Some,
6
+ isOption,
7
+ isResult,
6
8
  promiseToResult,
7
9
  type AsyncIOResult,
8
10
  type AsyncOption,