From 9160e6c4c9555415d67d019e42c7fad6737f00f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20P=C3=B6hls?= Date: Mon, 13 Jun 2022 09:28:26 +0200 Subject: [PATCH] add macroable docs --- packages/macroable.md | 50 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/macroable.md b/packages/macroable.md index 4d699c5..b4dd2a1 100644 --- a/packages/macroable.md +++ b/packages/macroable.md @@ -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' @@ -46,6 +59,7 @@ class User extends Macroable { private firstname: string = 'Supercharge' } +// in another file/package User.macro('hello', function () { return `Hello ${this.firstname}!` }) @@ -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: @@ -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.