fp-pack 0.1.0 → 0.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.
- package/README.md +27 -7
- package/dist/fp-pack.umd.js +1 -1
- package/dist/fp-pack.umd.js.map +1 -1
- package/dist/implement/async/index.d.ts +1 -0
- package/dist/implement/async/index.d.ts.map +1 -1
- package/dist/implement/async/pipeAsyncSideEffectStrict.d.ts +57 -0
- package/dist/implement/async/pipeAsyncSideEffectStrict.d.ts.map +1 -0
- package/dist/implement/async/pipeAsyncSideEffectStrict.mjs +16 -0
- package/dist/implement/async/pipeAsyncSideEffectStrict.mjs.map +1 -0
- package/dist/implement/composition/from.d.ts +6 -0
- package/dist/implement/composition/from.d.ts.map +1 -0
- package/dist/implement/composition/from.mjs +7 -0
- package/dist/implement/composition/from.mjs.map +1 -0
- package/dist/implement/composition/index.d.ts +2 -0
- package/dist/implement/composition/index.d.ts.map +1 -1
- package/dist/implement/composition/pipe.d.ts +6 -0
- package/dist/implement/composition/pipe.d.ts.map +1 -1
- package/dist/implement/composition/pipe.mjs.map +1 -1
- package/dist/implement/composition/pipe.type-test.d.ts +29 -0
- package/dist/implement/composition/pipe.type-test.d.ts.map +1 -1
- package/dist/implement/composition/pipeSideEffect.d.ts +6 -0
- package/dist/implement/composition/pipeSideEffect.d.ts.map +1 -1
- package/dist/implement/composition/pipeSideEffect.mjs.map +1 -1
- package/dist/implement/composition/pipeSideEffectStrict.d.ts +53 -0
- package/dist/implement/composition/pipeSideEffectStrict.d.ts.map +1 -0
- package/dist/implement/composition/pipeSideEffectStrict.mjs +16 -0
- package/dist/implement/composition/pipeSideEffectStrict.mjs.map +1 -0
- package/dist/implement/control/ifElse.d.ts +4 -3
- package/dist/implement/control/ifElse.d.ts.map +1 -1
- package/dist/implement/control/ifElse.mjs.map +1 -1
- package/dist/implement/control/unless.d.ts +14 -2
- package/dist/implement/control/unless.d.ts.map +1 -1
- package/dist/implement/control/unless.mjs.map +1 -1
- package/dist/implement/control/when.d.ts +14 -2
- package/dist/implement/control/when.d.ts.map +1 -1
- package/dist/implement/control/when.mjs.map +1 -1
- package/dist/implement/object/index.d.ts +1 -0
- package/dist/implement/object/index.d.ts.map +1 -1
- package/dist/implement/object/propStrict.d.ts +7 -0
- package/dist/implement/object/propStrict.d.ts.map +1 -0
- package/dist/implement/object/propStrict.mjs +12 -0
- package/dist/implement/object/propStrict.mjs.map +1 -0
- package/dist/index.mjs +248 -240
- package/dist/index.mjs.map +1 -1
- package/dist/skills/fp-pack/SKILL.md +1699 -0
- package/dist/skills/fp-pack.md +56 -8
- package/package.json +1 -1
- package/src/implement/async/index.ts +1 -0
- package/src/implement/async/pipeAsyncSideEffectStrict.test.ts +23 -0
- package/src/implement/async/pipeAsyncSideEffectStrict.ts +140 -0
- package/src/implement/composition/from.test.ts +16 -0
- package/src/implement/composition/from.ts +8 -0
- package/src/implement/composition/index.ts +2 -0
- package/src/implement/composition/pipe.test.ts +8 -0
- package/src/implement/composition/pipe.ts +12 -0
- package/src/implement/composition/pipe.type-test.ts +49 -0
- package/src/implement/composition/pipeSideEffect.test.ts +8 -0
- package/src/implement/composition/pipeSideEffect.ts +17 -0
- package/src/implement/composition/pipeSideEffectStrict.test.ts +23 -0
- package/src/implement/composition/pipeSideEffectStrict.ts +134 -0
- package/src/implement/control/curried.test.ts +18 -0
- package/src/implement/control/ifElse.ts +5 -3
- package/src/implement/control/unless.ts +20 -2
- package/src/implement/control/when.ts +20 -2
- package/src/implement/object/index.ts +1 -0
- package/src/implement/object/propStrict.test.ts +29 -0
- package/src/implement/object/propStrict.ts +20 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import SideEffect, { isSideEffect } from './sideEffect';
|
|
2
|
+
|
|
3
|
+
type AnyFn = (...args: any[]) => any;
|
|
4
|
+
type MaybeSideEffect<T, E> = T | SideEffect<E>;
|
|
5
|
+
type NonSideEffect<T> = Exclude<T, SideEffect<any>>;
|
|
6
|
+
type UnaryFn<A, R> = (a: A) => R;
|
|
7
|
+
type ZeroFn<R> = () => R;
|
|
8
|
+
|
|
9
|
+
type EffectOfReturn<R> = R extends SideEffect<infer E> ? E : never;
|
|
10
|
+
type EffectOfFn<F> = F extends (...args: any[]) => infer R ? EffectOfReturn<R> : never;
|
|
11
|
+
type EffectsOf<Fns extends AnyFn[]> = EffectOfFn<Fns[number]>;
|
|
12
|
+
|
|
13
|
+
type PipeValueOutputUnary<Fns extends UnaryFn<any, any>[]> = Fns extends [UnaryFn<any, infer R>]
|
|
14
|
+
? NonSideEffect<R>
|
|
15
|
+
: Fns extends [UnaryFn<any, infer R>, ...infer Rest]
|
|
16
|
+
? Rest extends [UnaryFn<NonSideEffect<R>, any>, ...UnaryFn<any, any>[]]
|
|
17
|
+
? PipeValueOutputUnary<Rest>
|
|
18
|
+
: never
|
|
19
|
+
: never;
|
|
20
|
+
|
|
21
|
+
type PipeValueOutputStrict<Fns extends [AnyFn, ...AnyFn[]]> =
|
|
22
|
+
Fns extends [ZeroFn<infer R>]
|
|
23
|
+
? NonSideEffect<R>
|
|
24
|
+
: Fns extends [ZeroFn<infer R>, ...infer Rest]
|
|
25
|
+
? Rest extends [UnaryFn<NonSideEffect<R>, any>, ...UnaryFn<any, any>[]]
|
|
26
|
+
? PipeValueOutputUnary<Rest>
|
|
27
|
+
: never
|
|
28
|
+
: Fns extends [UnaryFn<any, any>, ...UnaryFn<any, any>[]]
|
|
29
|
+
? PipeValueOutputUnary<Fns>
|
|
30
|
+
: never;
|
|
31
|
+
|
|
32
|
+
type PipeInputStrict<Fns extends [AnyFn, ...AnyFn[]]> = Fns extends [ZeroFn<any>, ...AnyFn[]]
|
|
33
|
+
? never
|
|
34
|
+
: Fns extends [UnaryFn<infer A, any>, ...AnyFn[]]
|
|
35
|
+
? A
|
|
36
|
+
: never;
|
|
37
|
+
|
|
38
|
+
type Resolve<T> = T extends infer R ? R : never;
|
|
39
|
+
|
|
40
|
+
type PipeSideEffectStrictUnary<Fns extends [AnyFn, ...AnyFn[]]> = {
|
|
41
|
+
(input: PipeInputStrict<Fns>): Resolve<MaybeSideEffect<PipeValueOutputStrict<Fns>, EffectsOf<Fns>>>;
|
|
42
|
+
<EIn>(
|
|
43
|
+
input: PipeInputStrict<Fns> | SideEffect<EIn>
|
|
44
|
+
): Resolve<MaybeSideEffect<PipeValueOutputStrict<Fns>, EffectsOf<Fns> | EIn>>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type PipeSideEffectStrict<Fns extends [AnyFn, ...AnyFn[]]> = Fns extends [ZeroFn<any>, ...AnyFn[]]
|
|
48
|
+
? () => Resolve<MaybeSideEffect<PipeValueOutputStrict<Fns>, EffectsOf<Fns>>>
|
|
49
|
+
: PipeSideEffectStrictUnary<Fns>;
|
|
50
|
+
|
|
51
|
+
function pipeSideEffectStrict<R>(ab: ZeroFn<R>): PipeSideEffectStrict<[ZeroFn<R>]>;
|
|
52
|
+
function pipeSideEffectStrict<B, R>(
|
|
53
|
+
ab: ZeroFn<B>,
|
|
54
|
+
bc: UnaryFn<NonSideEffect<B>, R>
|
|
55
|
+
): PipeSideEffectStrict<[ZeroFn<B>, UnaryFn<NonSideEffect<B>, R>]>;
|
|
56
|
+
function pipeSideEffectStrict<B, C, R>(
|
|
57
|
+
ab: ZeroFn<B>,
|
|
58
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
59
|
+
cd: UnaryFn<NonSideEffect<C>, R>
|
|
60
|
+
): PipeSideEffectStrict<[ZeroFn<B>, UnaryFn<NonSideEffect<B>, C>, UnaryFn<NonSideEffect<C>, R>]>;
|
|
61
|
+
function pipeSideEffectStrict<B, C, D, R>(
|
|
62
|
+
ab: ZeroFn<B>,
|
|
63
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
64
|
+
cd: UnaryFn<NonSideEffect<C>, D>,
|
|
65
|
+
de: UnaryFn<NonSideEffect<D>, R>
|
|
66
|
+
): PipeSideEffectStrict<[
|
|
67
|
+
ZeroFn<B>,
|
|
68
|
+
UnaryFn<NonSideEffect<B>, C>,
|
|
69
|
+
UnaryFn<NonSideEffect<C>, D>,
|
|
70
|
+
UnaryFn<NonSideEffect<D>, R>
|
|
71
|
+
]>;
|
|
72
|
+
function pipeSideEffectStrict<B, C, D, E, R>(
|
|
73
|
+
ab: ZeroFn<B>,
|
|
74
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
75
|
+
cd: UnaryFn<NonSideEffect<C>, D>,
|
|
76
|
+
de: UnaryFn<NonSideEffect<D>, E>,
|
|
77
|
+
ef: UnaryFn<NonSideEffect<E>, R>
|
|
78
|
+
): PipeSideEffectStrict<[
|
|
79
|
+
ZeroFn<B>,
|
|
80
|
+
UnaryFn<NonSideEffect<B>, C>,
|
|
81
|
+
UnaryFn<NonSideEffect<C>, D>,
|
|
82
|
+
UnaryFn<NonSideEffect<D>, E>,
|
|
83
|
+
UnaryFn<NonSideEffect<E>, R>
|
|
84
|
+
]>;
|
|
85
|
+
function pipeSideEffectStrict<A, R>(ab: UnaryFn<A, R>): PipeSideEffectStrict<[UnaryFn<A, R>]>;
|
|
86
|
+
function pipeSideEffectStrict<A, B, R>(
|
|
87
|
+
ab: UnaryFn<A, B>,
|
|
88
|
+
bc: UnaryFn<NonSideEffect<B>, R>
|
|
89
|
+
): PipeSideEffectStrict<[UnaryFn<A, B>, UnaryFn<NonSideEffect<B>, R>]>;
|
|
90
|
+
function pipeSideEffectStrict<A, B, C, R>(
|
|
91
|
+
ab: UnaryFn<A, B>,
|
|
92
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
93
|
+
cd: UnaryFn<NonSideEffect<C>, R>
|
|
94
|
+
): PipeSideEffectStrict<[UnaryFn<A, B>, UnaryFn<NonSideEffect<B>, C>, UnaryFn<NonSideEffect<C>, R>]>;
|
|
95
|
+
function pipeSideEffectStrict<A, B, C, D, R>(
|
|
96
|
+
ab: UnaryFn<A, B>,
|
|
97
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
98
|
+
cd: UnaryFn<NonSideEffect<C>, D>,
|
|
99
|
+
de: UnaryFn<NonSideEffect<D>, R>
|
|
100
|
+
): PipeSideEffectStrict<[
|
|
101
|
+
UnaryFn<A, B>,
|
|
102
|
+
UnaryFn<NonSideEffect<B>, C>,
|
|
103
|
+
UnaryFn<NonSideEffect<C>, D>,
|
|
104
|
+
UnaryFn<NonSideEffect<D>, R>
|
|
105
|
+
]>;
|
|
106
|
+
function pipeSideEffectStrict<A, B, C, D, E, R>(
|
|
107
|
+
ab: UnaryFn<A, B>,
|
|
108
|
+
bc: UnaryFn<NonSideEffect<B>, C>,
|
|
109
|
+
cd: UnaryFn<NonSideEffect<C>, D>,
|
|
110
|
+
de: UnaryFn<NonSideEffect<D>, E>,
|
|
111
|
+
ef: UnaryFn<NonSideEffect<E>, R>
|
|
112
|
+
): PipeSideEffectStrict<[
|
|
113
|
+
UnaryFn<A, B>,
|
|
114
|
+
UnaryFn<NonSideEffect<B>, C>,
|
|
115
|
+
UnaryFn<NonSideEffect<C>, D>,
|
|
116
|
+
UnaryFn<NonSideEffect<D>, E>,
|
|
117
|
+
UnaryFn<NonSideEffect<E>, R>
|
|
118
|
+
]>;
|
|
119
|
+
|
|
120
|
+
function pipeSideEffectStrict<Fns extends [AnyFn, ...AnyFn[]]>(...funcs: Fns): PipeSideEffectStrict<Fns>;
|
|
121
|
+
function pipeSideEffectStrict(...funcs: Array<(input: any) => any>) {
|
|
122
|
+
return (init?: any) => {
|
|
123
|
+
let acc = init;
|
|
124
|
+
for (const fn of funcs) {
|
|
125
|
+
if (isSideEffect(acc)) {
|
|
126
|
+
return acc;
|
|
127
|
+
}
|
|
128
|
+
acc = fn(acc);
|
|
129
|
+
}
|
|
130
|
+
return acc;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default pipeSideEffectStrict;
|
|
@@ -68,4 +68,22 @@ describe('control (curried)', () => {
|
|
|
68
68
|
expect(applyWhen(5)).toBe(5);
|
|
69
69
|
expect(applyWhen(20)).toBe(21);
|
|
70
70
|
});
|
|
71
|
+
|
|
72
|
+
it('infers types across curried stages', () => {
|
|
73
|
+
const predicate = (value: number) => value > 0;
|
|
74
|
+
const onTrue = (value: number) => value * 2;
|
|
75
|
+
const onFalse = (value: number) => value - 2;
|
|
76
|
+
|
|
77
|
+
const choose = ifElse(predicate)(onTrue)(onFalse);
|
|
78
|
+
expect(choose(3)).toBe(6);
|
|
79
|
+
expect(choose(-1)).toBe(-3);
|
|
80
|
+
|
|
81
|
+
const applyWhen = when(predicate)((value) => value + 1);
|
|
82
|
+
const applyUnless = unless(predicate)((value) => value + 1);
|
|
83
|
+
|
|
84
|
+
expect(applyWhen(2)).toBe(3);
|
|
85
|
+
expect(applyWhen(-2)).toBe(-2);
|
|
86
|
+
expect(applyUnless(2)).toBe(2);
|
|
87
|
+
expect(applyUnless(-2)).toBe(-1);
|
|
88
|
+
});
|
|
71
89
|
});
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import curry from '../composition/curry';
|
|
2
2
|
|
|
3
|
+
type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
4
|
+
|
|
3
5
|
type IfElse = {
|
|
4
6
|
<T, RTrue, RFalse>(
|
|
5
7
|
...args: [predicate: (value: T) => boolean]
|
|
6
8
|
): (onTrue: (value: T) => RTrue) => (onFalse: (value: T) => RFalse) => (value: T) => RTrue | RFalse;
|
|
7
9
|
<T, RTrue, RFalse>(
|
|
8
|
-
...args: [predicate: (value: T) => boolean, onTrue: (value: T) => RTrue]
|
|
10
|
+
...args: [predicate: (value: NoInfer<T>) => boolean, onTrue: (value: T) => RTrue]
|
|
9
11
|
): (onFalse: (value: T) => RFalse) => (value: T) => RTrue | RFalse;
|
|
10
12
|
<T, RTrue, RFalse>(
|
|
11
13
|
...args: [
|
|
12
|
-
predicate: (value: T) => boolean,
|
|
14
|
+
predicate: (value: NoInfer<T>) => boolean,
|
|
13
15
|
onTrue: (value: T) => RTrue,
|
|
14
16
|
onFalse: (value: T) => RFalse
|
|
15
17
|
]
|
|
16
18
|
): (value: T) => RTrue | RFalse;
|
|
17
19
|
<T, RTrue, RFalse>(
|
|
18
20
|
...args: [
|
|
19
|
-
predicate: (value: T) => boolean,
|
|
21
|
+
predicate: (value: NoInfer<T>) => boolean,
|
|
20
22
|
onTrue: (value: T) => RTrue,
|
|
21
23
|
onFalse: (value: T) => RFalse,
|
|
22
24
|
value: T
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import curry from '../composition/curry';
|
|
2
2
|
|
|
3
|
+
type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
3
4
|
type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
4
5
|
|
|
5
6
|
type Unless = {
|
|
6
7
|
<T>(...args: [predicate: (value: Widen<T>) => boolean]): (
|
|
7
8
|
fn: (value: Widen<T>) => Widen<T>
|
|
8
9
|
) => (value: Widen<T>) => Widen<T>;
|
|
10
|
+
<T, R>(...args: [predicate: (value: Widen<T>) => boolean]): (
|
|
11
|
+
fn: (value: Widen<T>) => R
|
|
12
|
+
) => (value: Widen<T>) => Widen<T> | R;
|
|
9
13
|
<T>(
|
|
10
|
-
...args: [predicate: (value: Widen<T
|
|
14
|
+
...args: [predicate: (value: NoInfer<Widen<T>>) => boolean, fn: (value: Widen<T>) => Widen<T>]
|
|
11
15
|
): (value: Widen<T>) => Widen<T>;
|
|
16
|
+
<T, R>(
|
|
17
|
+
...args: [predicate: (value: NoInfer<Widen<T>>) => boolean, fn: (value: Widen<T>) => R]
|
|
18
|
+
): (value: Widen<T>) => Widen<T> | R;
|
|
12
19
|
<T>(
|
|
13
|
-
...args: [
|
|
20
|
+
...args: [
|
|
21
|
+
predicate: (value: NoInfer<Widen<T>>) => boolean,
|
|
22
|
+
fn: (value: Widen<T>) => Widen<T>,
|
|
23
|
+
value: Widen<T>
|
|
24
|
+
]
|
|
14
25
|
): Widen<T>;
|
|
26
|
+
<T, R>(
|
|
27
|
+
...args: [
|
|
28
|
+
predicate: (value: NoInfer<Widen<T>>) => boolean,
|
|
29
|
+
fn: (value: Widen<T>) => R,
|
|
30
|
+
value: Widen<T>
|
|
31
|
+
]
|
|
32
|
+
): Widen<T> | R;
|
|
15
33
|
};
|
|
16
34
|
|
|
17
35
|
/**
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import curry from '../composition/curry';
|
|
2
2
|
|
|
3
|
+
type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
3
4
|
type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
4
5
|
|
|
5
6
|
type When = {
|
|
6
7
|
<T>(...args: [predicate: (value: Widen<T>) => boolean]): (
|
|
7
8
|
fn: (value: Widen<T>) => Widen<T>
|
|
8
9
|
) => (value: Widen<T>) => Widen<T>;
|
|
10
|
+
<T, R>(...args: [predicate: (value: Widen<T>) => boolean]): (
|
|
11
|
+
fn: (value: Widen<T>) => R
|
|
12
|
+
) => (value: Widen<T>) => Widen<T> | R;
|
|
9
13
|
<T>(
|
|
10
|
-
...args: [predicate: (value: Widen<T
|
|
14
|
+
...args: [predicate: (value: NoInfer<Widen<T>>) => boolean, fn: (value: Widen<T>) => Widen<T>]
|
|
11
15
|
): (value: Widen<T>) => Widen<T>;
|
|
16
|
+
<T, R>(
|
|
17
|
+
...args: [predicate: (value: NoInfer<Widen<T>>) => boolean, fn: (value: Widen<T>) => R]
|
|
18
|
+
): (value: Widen<T>) => Widen<T> | R;
|
|
12
19
|
<T>(
|
|
13
|
-
...args: [
|
|
20
|
+
...args: [
|
|
21
|
+
predicate: (value: NoInfer<Widen<T>>) => boolean,
|
|
22
|
+
fn: (value: Widen<T>) => Widen<T>,
|
|
23
|
+
value: Widen<T>
|
|
24
|
+
]
|
|
14
25
|
): Widen<T>;
|
|
26
|
+
<T, R>(
|
|
27
|
+
...args: [
|
|
28
|
+
predicate: (value: NoInfer<Widen<T>>) => boolean,
|
|
29
|
+
fn: (value: Widen<T>) => R,
|
|
30
|
+
value: Widen<T>
|
|
31
|
+
]
|
|
32
|
+
): Widen<T> | R;
|
|
15
33
|
};
|
|
16
34
|
|
|
17
35
|
/**
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import propStrict from './propStrict';
|
|
3
|
+
|
|
4
|
+
describe('propStrict', () => {
|
|
5
|
+
it('gets a property', () => {
|
|
6
|
+
const user = { id: 1, name: 'A' };
|
|
7
|
+
expect(propStrict('name', user)).toBe('A');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('supports currying', () => {
|
|
11
|
+
const user = { name: 'A' };
|
|
12
|
+
const getName = propStrict('name');
|
|
13
|
+
expect(getName(user)).toBe('A');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('throws when property is missing', () => {
|
|
17
|
+
type User = { name: string; age?: number };
|
|
18
|
+
const user: User = { name: 'A' };
|
|
19
|
+
expect(() => propStrict('age', user)).toThrow(/propStrict/);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('throws when value is null or undefined', () => {
|
|
23
|
+
const nullUser: { name: string | null } = { name: null };
|
|
24
|
+
expect(() => propStrict('name', nullUser)).toThrow(/propStrict/);
|
|
25
|
+
|
|
26
|
+
const undefinedUser: { name: string | undefined } = { name: undefined };
|
|
27
|
+
expect(() => propStrict('name', undefinedUser)).toThrow(/propStrict/);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import curry from '../composition/curry';
|
|
2
|
+
|
|
3
|
+
type PropStrict = {
|
|
4
|
+
<K extends PropertyKey>(...args: [key: K]): <T extends Record<K, unknown>>(obj: T) => NonNullable<T[K]>;
|
|
5
|
+
<T, K extends keyof T>(...args: [key: K, obj: T]): NonNullable<T[K]>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* propStrict - strict property access (throws on null/undefined)
|
|
10
|
+
*/
|
|
11
|
+
function propStrict<T, K extends keyof T = keyof T>(key: K, obj: T): NonNullable<T[K]> {
|
|
12
|
+
const value = obj?.[key];
|
|
13
|
+
if (value == null) {
|
|
14
|
+
throw new Error(`propStrict: "${String(key)}" is null or undefined`);
|
|
15
|
+
}
|
|
16
|
+
return value as NonNullable<T[K]>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const curriedPropStrict = curry(propStrict) as unknown as PropStrict;
|
|
20
|
+
export default curriedPropStrict;
|