Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
CXuesong committed Jul 28, 2024
1 parent 50f9e2e commit 5417ee6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
27 changes: 27 additions & 0 deletions packages/jscorlib/src/pipables/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
/**
* This module contains some helpers borrowing some of basic the concepts from [ES pipe operator](https://tc39.es/proposal-pipeline-operator/),
* enabling extending methods to existing objects in a tree-shaking-friendly way.
*
* ```ts
* // ES pipe operator (2021)
* x |> func1(%, a)
* |> func2(%, b)
* |> func3(%, c)
*
* // Pipables (this module)
* let x: PipeTarget;
* x.$(func1(a))
* .$(func2(b))
* .$(func3(c))
* ```
*
* To enable usage with pipe functions, an object should implement {@link PipeTarget} interface (the `$` method).
*
* Pipe functions should be compatible with {@link PipeFunction}. Refer to the type definition documentation for more information.
*
* @see [TC 39 Stage 2 Draft: ES pipe operator](https://tc39.es/proposal-pipeline-operator/)
*
* @module
*/
import { PipeFunction, PipeTarget } from "./typing";

export * from "./typing";
29 changes: 29 additions & 0 deletions packages/jscorlib/src/pipables/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,40 @@ We will have to design the extension methods this way due to
https://github.com/microsoft/TypeScript/issues/41709
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* A function applicable to the {@link PipeTarget}.
*
* Pipe functions are functions that, when invoked, returns another function, i.e., {@link PipeBody}, that only accepts 1 parameter,
* i.e., {@link PipeTarget}.
*
* Since TypeScript 4.9, you can use the following idiom to ensure your pipe function is compatible.
*
* ```ts
* function myPipeFunction(arg1: number): PipeBody<Target, string> {
* return target => {
* // ...
* return "result";
* };
* }
*
* // Ensures type compatibility.
* myPipeFunction satisfies PipeFunction;
* ```
*/
export type PipeFunction<TTarget = any, TArgs extends any[] = any[], TReturnValue = any> = (...args: TArgs) => PipeBody<TTarget, TReturnValue>;

/**
* The return type of {@link PipeFunction}. This is a function that will be eventually invoked
* directly with the {@link PipeTarget}.
*/
export type PipeBody<TTarget = any, TReturnValue = any> = (target: TTarget) => TReturnValue;
/* eslint-enable @typescript-eslint/no-explicit-any */

export interface PipeTarget {
/**
* Applies the current object (`this`) to the specified pipe function result.
*
* @param pipeBody an unary function, usually the return value of {@link PipeFunction}.
*/
$<T>(pipeBody: PipeBody<this, T>): T;
}

0 comments on commit 5417ee6

Please sign in to comment.