Skip to content

Commit

Permalink
add macroable docs
Browse files Browse the repository at this point in the history
  • Loading branch information
marcuspoehls committed Jun 13, 2022
1 parent 9766590 commit 9160e6c
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions packages/macroable.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,26 @@ const { Macroable } = require('@supercharge/macroable')


## Traditional Approach
The typical approach extending a JavaScript class is applying a custom function to the class’ prototype. This adds the given function to the class and makes it callablel on class instances. Here’s how you would do it:

```ts
class User {
private firstname: string = 'Supercharge'
}

// in another file/package
User.prototype.greet = function () {
return `Hello ${this.firstname}!`
}
```


## Using Macroable
Tba.
The `Macroable` class is a base class exposing methods to extends a class prototype in a declarative way. We call this declarative way "adding a macro". You may also determine whether a method is macro’ed to the class. Or you can remove all macros from a class.


### Adding Macros
Tba.
Add a macro to a class by extending the `Macroable` class and calling the static `Class.macro(name, method)` function:

```js
import { Macroable } from '@supercharge/macroable'
Expand All @@ -46,6 +59,7 @@ class User extends Macroable {
private firstname: string = 'Supercharge'
}

// in another file/package
User.macro('hello', function () {
return `Hello ${this.firstname}!`
})
Expand All @@ -58,12 +72,34 @@ user.hello()


### Has Macro
You can remove all macros from a class using the static `flushMacros` method:
You may determine whether a function on a class was added as a macro using the `hasMacro` method:

```ts
Macroable.hasMacro('method-name')
```

Here’s an example of checking whether a class’s method is a macro function:

```ts
import { Macroable } from '@supercharge/macroable'

class User extends Macroable {
greeting(): string {
return 'Hello World!'
}
}

User.macro('hello', function () {
return `Hello ${this.firstname}!`
})

User.hasMacro('hello')
// true

User.hasMacro('greeting')
// false -- because "greeting" was not macro’ed to the class
```


### Deleting Macros
You can remove all macros from a class using the static `flushMacros` method:
Expand Down Expand Up @@ -94,14 +130,16 @@ user.hello


## Adding IntelliSense
Tba.
A shortcoming for macros are IntelliSense in your editor. During development you want your editor to show autocompletions while typing. Dynamically adding methods to a class using macros won’t add type definitions to your code.

Use TypeScript interface merging.
A way to add IntelliSense support is using TypeScript’s interface merging. For example, the `HttpRequest` class in the Supercharge framework is macroable. Any third-party package adding methods to the request can also inject typings using declaration merging. Merge your types by defining a module for the extended package and export the extended interface:

```ts
declare module '@supercharge/http' {
export class Request {
export interface HttpRequest {
session(): Session
}
}
```

You should add the extended interface declarations in your typings file (typically a `.d.ts` file) or in one of your package’s exported files.

0 comments on commit 9160e6c

Please sign in to comment.