fp-pack 0.5.0 → 0.6.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.
Files changed (51) hide show
  1. package/README.md +16 -15
  2. package/dist/fp-pack.umd.js.map +1 -1
  3. package/dist/implement/composition/curry.d.ts +5 -5
  4. package/dist/implement/composition/curry.d.ts.map +1 -1
  5. package/dist/implement/composition/curry.mjs.map +1 -1
  6. package/dist/implement/composition/index.d.ts +3 -0
  7. package/dist/implement/composition/index.d.ts.map +1 -1
  8. package/dist/implement/composition/pipe.d.ts +3 -0
  9. package/dist/implement/composition/pipe.d.ts.map +1 -1
  10. package/dist/implement/composition/pipe.mjs.map +1 -1
  11. package/dist/implement/composition/pipe.type-test.d.ts +7 -1
  12. package/dist/implement/composition/pipe.type-test.d.ts.map +1 -1
  13. package/dist/implement/composition/sideEffect.d.ts +1 -1
  14. package/dist/implement/composition/sideEffect.d.ts.map +1 -1
  15. package/dist/implement/composition/sideEffect.mjs.map +1 -1
  16. package/dist/implement/object/assocPath.d.ts +2 -1
  17. package/dist/implement/object/assocPath.d.ts.map +1 -1
  18. package/dist/implement/object/assocPath.mjs.map +1 -1
  19. package/dist/implement/object/dissocPath.d.ts +2 -1
  20. package/dist/implement/object/dissocPath.d.ts.map +1 -1
  21. package/dist/implement/object/dissocPath.mjs.map +1 -1
  22. package/dist/implement/object/index.d.ts +1 -0
  23. package/dist/implement/object/index.d.ts.map +1 -1
  24. package/dist/implement/object/path.d.ts +4 -2
  25. package/dist/implement/object/path.d.ts.map +1 -1
  26. package/dist/implement/object/path.mjs.map +1 -1
  27. package/dist/implement/object/pathKey.d.ts +2 -0
  28. package/dist/implement/object/pathKey.d.ts.map +1 -0
  29. package/dist/implement/object/pathOr.d.ts +5 -3
  30. package/dist/implement/object/pathOr.d.ts.map +1 -1
  31. package/dist/implement/object/pathOr.mjs.map +1 -1
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/skills/fp-pack/SKILL.md +18 -16
  35. package/dist/skills/fp-pack.md +18 -16
  36. package/dist/stream/index.d.ts +1 -0
  37. package/dist/stream/index.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/src/implement/composition/curry.ts +5 -5
  40. package/src/implement/composition/index.ts +3 -0
  41. package/src/implement/composition/pipe.ts +4 -0
  42. package/src/implement/composition/pipe.type-test.ts +17 -1
  43. package/src/implement/composition/sideEffect.ts +1 -1
  44. package/src/implement/object/assocPath.ts +2 -2
  45. package/src/implement/object/dissocPath.ts +2 -2
  46. package/src/implement/object/index.ts +1 -0
  47. package/src/implement/object/path.ts +5 -3
  48. package/src/implement/object/pathKey.ts +1 -0
  49. package/src/implement/object/pathOr.ts +6 -4
  50. package/src/index.ts +3 -0
  51. package/src/stream/index.ts +1 -0
@@ -1,6 +1,6 @@
1
1
  # fp-pack AI Agent Skills
2
2
 
3
- Document Version: 0.5.0
3
+ Document Version: 0.6.0
4
4
 
5
5
  This document provides guidelines for AI coding assistants when working in projects that use fp-pack. Follow these instructions to write clean, declarative, functional code using fp-pack's utilities.
6
6
 
@@ -122,7 +122,7 @@ const finalValue = runPipeResult(processDataPipeline(input));
122
122
  **Key SideEffect functions:**
123
123
  - `SideEffect.of(fn, label?)` - Create a side effect container
124
124
  - `isSideEffect(value)` - Type guard for **runtime checking** whether a value is a SideEffect
125
- - `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines, provide generics for type safety). **⚠️ CRITICAL:** `runPipeResult<T, R=any>` has default `R=any`, so using it without generics returns `any` type. Always provide generics for type safety
125
+ - `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines). If the input type is precise, inference is preserved. If the input is widened to `SideEffect<any>` or `any`, the result becomes `any` unless you provide generics.
126
126
  - `matchSideEffect(result, { value, effect })` - Pattern match on result
127
127
 
128
128
  **Type-safe result handling:**
@@ -140,32 +140,34 @@ const processNumbers = pipeSideEffect(
140
140
 
141
141
  const result = processNumbers([1, 2, 3, 4, 5]);
142
142
 
143
- // ✅ CORRECT: Use isSideEffect for runtime checking + provide generics to runPipeResult
143
+ // ✅ CORRECT: Use isSideEffect for runtime checking
144
144
  if (!isSideEffect(result)) {
145
145
  // TypeScript knows: result is number[]
146
146
  const sum: number = result.reduce((a, b) => a + b, 0);
147
147
  } else {
148
148
  // TypeScript knows: result is SideEffect<string>
149
- // But runPipeResult still returns number[] | string (not fully narrowed)
150
- const error = runPipeResult<number[], string>(result); // error: number[] | string
149
+ // runPipeResult returns number[] | string (not fully narrowed)
150
+ const error = runPipeResult(result); // number[] | string
151
151
  }
152
152
 
153
- // WRONG: runPipeResult without generics
154
- const value = runPipeResult(result); // result: any (no type information!)
153
+ // ⚠️ If the result type is widened to SideEffect<any>, inference is lost
154
+ const widened: number[] | SideEffect<any> = result;
155
+ const unsafeValue = runPipeResult(widened); // number[] | any
155
156
 
156
- // ✅ CORRECT: Provide generics to runPipeResult
157
- const value = runPipeResult<number[], string>(result); // result: number[] | string (union type - safe but not narrowed)
157
+ // ✅ CORRECT: Provide generics to recover a safe union
158
+ const safeValue = runPipeResult<number[], string>(result); // result: number[] | string (union type - safe but not narrowed)
158
159
  ```
159
160
 
160
161
  **⚠️ CRITICAL: runPipeResult Type Safety**
161
162
 
162
163
  `runPipeResult<T, R=any>` has a default type parameter `R=any`. This means:
163
164
 
164
- - **Without generics**: `const result = runPipeResult(pipeline(data));` returns `any` type (unsafe!)
165
- - **With generics**: `runPipeResult<SuccessType, ErrorType>(result)` returns union type `SuccessType | ErrorType` (type-safe)
166
- - ✅ **With isSideEffect**: Use for runtime checking whether a value is SideEffect
165
+ - **Precise input types**: `T | SideEffect<'E'>` preserves `T | 'E'` without extra annotations.
166
+ - ⚠️ **Widened inputs**: `T | SideEffect<any>` (or `any`) collapses to `any`.
167
+ - ✅ **With generics**: `runPipeResult<SuccessType, ErrorType>(result)` restores a safe union when inference is lost.
168
+ - ✅ **With isSideEffect**: Prefer for runtime narrowing when you need branch-specific types.
167
169
 
168
- **Always provide generics to `runPipeResult`** for type safety. Use `isSideEffect` for runtime type checking.
170
+ Provide generics when inference is lost; prefer `isSideEffect` for precise narrowing.
169
171
 
170
172
  ## Stream Functions - Lazy Iterable Processing
171
173
 
@@ -520,7 +522,7 @@ const gradeToLetter = cond([
520
522
 
521
523
  - `prop` returns `T[K] | undefined`. Use `propOr` (or guard) before array operations.
522
524
  - `ifElse` expects **functions** for both branches. If you already have a value, wrap it: `() => value` or use `from(value)` for cleaner constant branches.
523
- - Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns).
525
+ - Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns). Pipelines that start with `from(...)` can be called without an initial input value.
524
526
  - `cond` returns `R | undefined`. Add a default branch and coalesce when you need a strict result.
525
527
  - In `pipeSideEffect`, keep step return types aligned to avoid wide unions.
526
528
 
@@ -673,8 +675,8 @@ const updateUser = assoc('lastLogin', new Date());
673
675
  - **Pure async operations**: `pipeAsync`
674
676
  - **Error handling with SideEffect**: `pipeSideEffect` (sync) / `pipeAsyncSideEffect` (async)
675
677
  - **Strict SideEffect unions**: `pipeSideEffectStrict` (sync) / `pipeAsyncSideEffectStrict` (async)
676
- - **Type-safe result handling**: `isSideEffect` for precise type narrowing (⚠️ **ALWAYS prefer this over bare `runPipeResult`** to avoid `any` types)
677
- - **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines). **⚠️ CRITICAL:** Returns `any` type without type narrowing due to default `R=any` parameter
678
+ - **Type-safe result handling**: `isSideEffect` for precise type narrowing (prefer this when you need branch-specific types)
679
+ - **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines). If the input is widened to `SideEffect<any>`/`any`, the result becomes `any`; provide generics to recover
678
680
  - **Large datasets**: `stream/*` functions
679
681
  - **Conditionals**: `ifElse`, `when`, `unless`, `cond`
680
682
  - **Object access**: `prop`, `propStrict`, `path`, `pick`, `omit`
@@ -21,4 +21,5 @@ export { default as toArray } from './toArray';
21
21
  export { default as toAsync } from './toAsync';
22
22
  export { default as zip } from './zip';
23
23
  export { default as zipWith } from './zipWith';
24
+ export type { AnyIterable, AnyIterableInput, PromiseLikeValue } from './utils';
24
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fp-pack",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Functional programming utilities library for TypeScript",
6
6
  "keywords": [
@@ -3,14 +3,14 @@
3
3
  * Supports functions with 2-5 parameters and keeps data-last call order.
4
4
  */
5
5
 
6
- type Curry2<Fn> = Fn extends (a: infer A, b: infer B) => infer R
6
+ export type Curry2<Fn> = Fn extends (a: infer A, b: infer B) => infer R
7
7
  ? {
8
8
  (...args: [A]): (b: B) => R;
9
9
  (...args: [A, B]): R;
10
10
  }
11
11
  : never;
12
12
 
13
- type Curry3<Fn> = Fn extends (a: infer A, b: infer B, c: infer C) => infer R
13
+ export type Curry3<Fn> = Fn extends (a: infer A, b: infer B, c: infer C) => infer R
14
14
  ? {
15
15
  (...args: [A]): (b: B) => (c: C) => R;
16
16
  (...args: [A, B]): (c: C) => R;
@@ -18,7 +18,7 @@ type Curry3<Fn> = Fn extends (a: infer A, b: infer B, c: infer C) => infer R
18
18
  }
19
19
  : never;
20
20
 
21
- type Curry4<Fn> = Fn extends (a: infer A, b: infer B, c: infer C, d: infer D) => infer R
21
+ export type Curry4<Fn> = Fn extends (a: infer A, b: infer B, c: infer C, d: infer D) => infer R
22
22
  ? {
23
23
  (...args: [A]): (b: B) => (c: C) => (d: D) => R;
24
24
  (...args: [A, B]): (c: C) => (d: D) => R;
@@ -27,7 +27,7 @@ type Curry4<Fn> = Fn extends (a: infer A, b: infer B, c: infer C, d: infer D) =>
27
27
  }
28
28
  : never;
29
29
 
30
- type Curry5<Fn> = Fn extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E) => infer R
30
+ export type Curry5<Fn> = Fn extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E) => infer R
31
31
  ? {
32
32
  (...args: [A]): (b: B) => (c: C) => (d: D) => (e: E) => R;
33
33
  (...args: [A, B]): (c: C) => (d: D) => (e: E) => R;
@@ -53,7 +53,7 @@ type CurryByArity<Fn extends (...args: any[]) => any> = Parameters<Fn>['length']
53
53
  ? Curry5<Fn>
54
54
  : CurryVariadic<Fn>;
55
55
 
56
- type Curried<Fn extends (...args: any[]) => any> = CurryByArity<Fn>;
56
+ export type Curried<Fn extends (...args: any[]) => any> = CurryByArity<Fn>;
57
57
 
58
58
  function curry<Fn extends (...args: any[]) => any>(fn: Fn): Curried<Fn>;
59
59
 
@@ -3,15 +3,18 @@ export { default as pipeSideEffect } from './pipeSideEffect';
3
3
  export { default as pipeSideEffectStrict } from './pipeSideEffectStrict';
4
4
  export { default as compose } from './compose';
5
5
  export { default as curry } from './curry';
6
+ export type { Curried, Curry2, Curry3, Curry4, Curry5 } from './curry';
6
7
  export { default as partial } from './partial';
7
8
  export { default as flip } from './flip';
8
9
  export { default as complement } from './complement';
9
10
  export { default as identity } from './identity';
10
11
  export { default as constant } from './constant';
11
12
  export { default as from } from './from';
13
+ export type { FromFn } from './from';
12
14
  export { default as tap } from './tap';
13
15
  export { default as once } from './once';
14
16
  export { default as memoize } from './memoize';
15
17
  export { default as SideEffect } from './sideEffect';
16
18
  export { SideEffect as SideEffectClass } from './sideEffect';
17
19
  export { isSideEffect, matchSideEffect, runPipeResult } from './sideEffect';
20
+ export type { MatchHandlers } from './sideEffect';
@@ -1,3 +1,5 @@
1
+ import type { FromFn } from './from';
2
+
1
3
  type UnaryFn<A, R> = (a: A) => R;
2
4
  type ZeroFn<R> = () => R;
3
5
  type PipeInput<Fns extends UnaryFn<any, any>[]> = Fns extends [UnaryFn<infer A, any>, ...UnaryFn<any, any>[]]
@@ -11,6 +13,7 @@ type PipeOutput<Fns extends UnaryFn<any, any>[]> = Fns extends [UnaryFn<any, inf
11
13
  : never
12
14
  : never;
13
15
  type Pipe<Fns extends UnaryFn<any, any>[]> = (input: PipeInput<Fns>) => PipeOutput<Fns>;
16
+ type PipeFrom<Fns extends [FromFn<any>, ...UnaryFn<any, any>[]]> = (input?: PipeInput<Fns>) => PipeOutput<Fns>;
14
17
 
15
18
  function pipe<R>(ab: ZeroFn<R>): () => R;
16
19
  function pipe<B, R>(ab: ZeroFn<B>, bc: UnaryFn<B, R>): () => R;
@@ -73,6 +76,7 @@ function pipe<B, C, D, E, F, G, H, I, J, R>(
73
76
  ij: UnaryFn<I, J>,
74
77
  jk: UnaryFn<J, R>
75
78
  ): () => R;
79
+ function pipe<Fns extends [FromFn<any>, ...UnaryFn<any, any>[]]>(...funcs: Fns): PipeFrom<Fns>;
76
80
  function pipe<A, R>(ab: UnaryFn<A, R>): (a: A) => R;
77
81
  function pipe<A, B, R>(ab: UnaryFn<A, B>, bc: UnaryFn<B, R>): (a: A) => R;
78
82
  function pipe<A, B, C, R>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, R>): (a: A) => R;
@@ -1,4 +1,4 @@
1
- import SideEffect from './sideEffect';
1
+ import SideEffect, { runPipeResult } from './sideEffect';
2
2
  import from from './from';
3
3
  import pipe from './pipe';
4
4
  import pipeSideEffect from './pipeSideEffect';
@@ -71,6 +71,13 @@ export const pipeFromTenValue = pipeFromTen('input');
71
71
  type PipeFromTenValueExpected = string;
72
72
  export type PipeFromTenValueIsStrict = Expect<Equal<typeof pipeFromTenValue, PipeFromTenValueExpected>>;
73
73
 
74
+ export const pipeFromTenValueNoInput = pipeFromTen();
75
+
76
+ type PipeFromTenValueNoInputExpected = string;
77
+ export type PipeFromTenValueNoInputIsStrict = Expect<
78
+ Equal<typeof pipeFromTenValueNoInput, PipeFromTenValueNoInputExpected>
79
+ >;
80
+
74
81
  export const pipeWithSideEffectInput = pipeSideEffect(
75
82
  (value: number) => value + 1,
76
83
  (value) => value * 2,
@@ -289,6 +296,15 @@ type StrictSideEffectValue = ValueUnion<typeof strictPipeSideEffectResult>;
289
296
  type StrictSideEffectValueExpected = number;
290
297
  export type PipeSideEffectStrictValue = Expect<Equal<StrictSideEffectValue, StrictSideEffectValueExpected>>;
291
298
 
299
+ export const strictPipeSideEffectRunResult = runPipeResult(strictPipeSideEffectResult);
300
+
301
+ type StrictPipeSideEffectRunExpected =
302
+ | ValueUnion<typeof strictPipeSideEffectResult>
303
+ | EffectUnion<typeof strictPipeSideEffectResult>;
304
+ export type PipeSideEffectStrictRunPipeResultIsStrict = Expect<
305
+ Equal<typeof strictPipeSideEffectRunResult, StrictPipeSideEffectRunExpected>
306
+ >;
307
+
292
308
  export const strictPipeSideEffectInput = strictPipeSideEffect(SideEffect.of(() => 'INPUT' as const));
293
309
 
294
310
  type StrictSideEffectInputEffects = EffectUnion<typeof strictPipeSideEffectInput>;
@@ -15,7 +15,7 @@ export class SideEffect<T = unknown> {
15
15
  }
16
16
  }
17
17
 
18
- type MatchHandlers<T, RValue, REffect> = {
18
+ export type MatchHandlers<T, RValue, REffect> = {
19
19
  value: (value: T) => RValue;
20
20
  effect: (sideEffect: SideEffect) => REffect;
21
21
  };
@@ -1,6 +1,5 @@
1
1
  import curry from '../composition/curry';
2
-
3
- type PathKey = string | number | symbol;
2
+ import type { PathKey } from './pathKey';
4
3
 
5
4
  const isIndexKey = (key: PathKey): key is number | `${number}` => {
6
5
  if (typeof key === 'number') {
@@ -62,3 +61,4 @@ function assocPath<T = unknown>(pathArray: PathKey[], value: unknown, obj: unkno
62
61
 
63
62
  const curriedAssocPath = curry(assocPath) as AssocPath;
64
63
  export default curriedAssocPath;
64
+ export type { PathKey };
@@ -1,6 +1,5 @@
1
1
  import curry from '../composition/curry';
2
-
3
- type PathKey = string | number | symbol;
2
+ import type { PathKey } from './pathKey';
4
3
 
5
4
  const isIndexKey = (key: PathKey): key is number | `${number}` => {
6
5
  if (typeof key === 'number') {
@@ -78,3 +77,4 @@ function dissocPath<T = unknown>(pathArray: PathKey[], obj: T): T {
78
77
 
79
78
  const curriedDissocPath = curry(dissocPath) as DissocPath;
80
79
  export default curriedDissocPath;
80
+ export type { PathKey };
@@ -19,3 +19,4 @@ export { default as mapValues } from './mapValues';
19
19
  export { default as evolve } from './evolve';
20
20
  export { default as has } from './has';
21
21
  export { default as hasPath } from './hasPath';
22
+ export type { PathKey } from './pathKey';
@@ -1,16 +1,18 @@
1
1
  import curry from '../composition/curry';
2
+ import type { PathKey } from './pathKey';
2
3
 
3
4
  type Path = {
4
- (pathArray: string[]): <T>(obj: any) => T | undefined;
5
- <T>(...args: [pathArray: string[], obj: any]): T | undefined;
5
+ (pathArray: PathKey[]): <T>(obj: any) => T | undefined;
6
+ <T>(...args: [pathArray: PathKey[], obj: any]): T | undefined;
6
7
  };
7
8
 
8
9
  /**
9
10
  * path - 안전한 깊은 프로퍼티 접근
10
11
  */
11
- function path<T>(pathArray: string[], obj: any): T | undefined {
12
+ function path<T>(pathArray: PathKey[], obj: any): T | undefined {
12
13
  return pathArray.reduce((current, key) => (current == null ? undefined : current[key]), obj) as T | undefined;
13
14
  }
14
15
 
15
16
  const curriedPath = curry(path) as Path;
16
17
  export default curriedPath;
18
+ export type { PathKey };
@@ -0,0 +1 @@
1
+ export type PathKey = string | number | symbol;
@@ -1,18 +1,20 @@
1
1
  import curry from '../composition/curry';
2
+ import type { PathKey } from './pathKey';
2
3
 
3
4
  type PathOr = {
4
- <D>(...args: [defaultValue: D]): <T>(pathArray: string[]) => (obj: any) => T | D;
5
- <D>(...args: [defaultValue: D, pathArray: string[]]): <T>(obj: any) => T | D;
6
- <T, D>(...args: [defaultValue: D, pathArray: string[], obj: any]): T | D;
5
+ <D>(...args: [defaultValue: D]): <T>(pathArray: PathKey[]) => (obj: any) => T | D;
6
+ <D>(...args: [defaultValue: D, pathArray: PathKey[]]): <T>(obj: any) => T | D;
7
+ <T, D>(...args: [defaultValue: D, pathArray: PathKey[], obj: any]): T | D;
7
8
  };
8
9
 
9
10
  /**
10
11
  * pathOr - 기본값이 있는 깊은 프로퍼티 접근
11
12
  */
12
- function pathOr<T, D>(defaultValue: D, pathArray: string[], obj: any): T | D {
13
+ function pathOr<T, D>(defaultValue: D, pathArray: PathKey[], obj: any): T | D {
13
14
  const value = pathArray.reduce((current, key) => (current == null ? undefined : current[key]), obj) as T | undefined;
14
15
  return value == null ? defaultValue : value;
15
16
  }
16
17
 
17
18
  const curriedPathOr = curry(pathOr) as PathOr;
18
19
  export default curriedPathOr;
20
+ export type { PathKey };
package/src/index.ts CHANGED
@@ -30,3 +30,6 @@ export * from './implement/nullable';
30
30
 
31
31
  // Debug
32
32
  export * from './implement/debug';
33
+
34
+ // Stream Types
35
+ export type { AnyIterable, AnyIterableInput, PromiseLikeValue } from './stream/utils';
@@ -21,3 +21,4 @@ export { default as toArray } from './toArray';
21
21
  export { default as toAsync } from './toAsync';
22
22
  export { default as zip } from './zip';
23
23
  export { default as zipWith } from './zipWith';
24
+ export type { AnyIterable, AnyIterableInput, PromiseLikeValue } from './utils';