Skip to content

Commit 173a289

Browse files
KhraksMamtsoveffect-bot
authored andcommitted
Add Pipeable.Class api (#4669)
1 parent 31a082e commit 173a289

File tree

4 files changed

+123
-3
lines changed

4 files changed

+123
-3
lines changed

.changeset/kind-poems-cough.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
"effect": minor
3+
---
4+
5+
Simplified the creation of pipeable classes.
6+
7+
```ts
8+
class MyClass extends Pipeable.Class() {
9+
constructor(public a: number) {
10+
super()
11+
}
12+
methodA() {
13+
return this.a
14+
}
15+
}
16+
console.log(new MyClass(2).pipe((x) => x.methodA())) // 2
17+
```
18+
19+
```ts
20+
class A {
21+
constructor(public a: number) {}
22+
methodA() {
23+
return this.a
24+
}
25+
}
26+
class B extends Pipeable.Class(A) {
27+
constructor(private b: string) {
28+
super(b.length)
29+
}
30+
methodB() {
31+
return [this.b, this.methodA()]
32+
}
33+
}
34+
console.log(new B("pipe").pipe((x) => x.methodB())) // ['pipe', 4]
35+
```

packages/effect/src/Pipeable.ts

+43-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
* @since 2.0.0
33
*/
44

5+
import type { Ctor } from "./Types.js"
6+
57
/**
68
* @since 2.0.0
7-
* @category models
9+
* @category Models
810
*/
911
export interface Pipeable {
1012
pipe<A>(this: A): A
@@ -522,3 +524,43 @@ export const pipeArguments = <A>(self: A, args: IArguments): unknown => {
522524
}
523525
}
524526
}
527+
528+
/**
529+
* @since 3.15.0
530+
* @category Models
531+
*/
532+
export interface PipeableConstructor {
533+
new(...args: Array<any>): Pipeable
534+
}
535+
536+
/**
537+
* @since 3.15.0
538+
* @category Prototypes
539+
*/
540+
export const Prototype: Pipeable = {
541+
pipe() {
542+
return pipeArguments(this, arguments)
543+
}
544+
}
545+
546+
const Base: PipeableConstructor = (function() {
547+
function PipeableBase() {}
548+
PipeableBase.prototype = Prototype
549+
return PipeableBase as any
550+
})()
551+
552+
/**
553+
* @since 3.15.0
554+
* @category Constructors
555+
*/
556+
export const Class: {
557+
(): PipeableConstructor
558+
<TBase extends Ctor>(klass: TBase): TBase & PipeableConstructor
559+
} = (klass?: Ctor) =>
560+
klass ?
561+
class extends klass {
562+
pipe() {
563+
return pipeArguments(this, arguments)
564+
}
565+
}
566+
: Base

packages/effect/src/Types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,8 @@ export type NotFunction<T> = T extends Function ? never : T
336336
* @since 3.9.0
337337
*/
338338
export type NoExcessProperties<T, U> = T & { readonly [K in Exclude<keyof U, keyof T>]: never }
339+
340+
/**
341+
* @since 3.15.0
342+
*/
343+
export type Ctor<T = {}> = new(...args: Array<any>) => T

packages/effect/test/Pipeable.test.ts

+40-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, it } from "@effect/vitest"
2-
import { assertSome } from "@effect/vitest/utils"
3-
import { Option } from "effect"
2+
import { assertInstanceOf, assertSome, deepStrictEqual } from "@effect/vitest/utils"
3+
import { Option, Pipeable } from "effect"
44

55
describe("Pipeable", () => {
66
it("pipeArguments", () => {
@@ -70,4 +70,42 @@ describe("Pipeable", () => {
7070
126
7171
)
7272
})
73+
it("pipeable", () => {
74+
class A {
75+
constructor(public a: number) {}
76+
methodA() {
77+
return this.a
78+
}
79+
}
80+
class B extends Pipeable.Class(A) {
81+
constructor(private b: string) {
82+
super(b.length)
83+
}
84+
methodB() {
85+
return [this.b, this.methodA()]
86+
}
87+
}
88+
const b = new B("bb")
89+
90+
assertInstanceOf(b, A)
91+
assertInstanceOf(b, B)
92+
deepStrictEqual(b.methodB(), ["bb", 2])
93+
deepStrictEqual(b.pipe((x) => x.methodB()), ["bb", 2])
94+
})
95+
it("Class", () => {
96+
class A extends Pipeable.Class() {
97+
constructor(public a: number) {
98+
super()
99+
}
100+
methodA() {
101+
return this.a
102+
}
103+
}
104+
const a = new A(2)
105+
106+
assertInstanceOf(a, A)
107+
assertInstanceOf(a, Pipeable.Class())
108+
deepStrictEqual(a.methodA(), 2)
109+
deepStrictEqual(a.pipe((x) => x.methodA()), 2)
110+
})
73111
})

0 commit comments

Comments
 (0)