Skip to content

Commit 96f5ce1

Browse files
committed
docs(furystack): byebye-extensions
1 parent 2c7c689 commit 96f5ce1

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
layout: post
3+
title: Bye-bye extension methods
4+
author: [gallayl]
5+
tags: ['FuryStack', 'core', 'filesystem-store', 'logging', 'mongodb-store', 'redis-store', 'repository', 'rest-service', 'security', 'sequelize-store', 'websocket-api', 'inject']
6+
image: img/008-byebye-extension-methods.jpg
7+
date: '2022-04-30T18:00:00.257Z'
8+
draft: false
9+
excerpt: Using extension methods was fun at the beginning but I've ran into more and more problems with them
10+
---
11+
12+
### The Heritage from C#
13+
14+
It's not a big sectet that one of the main inspiration for FuryStack is the .NET (legacy and Core) stack where extension methods are quite common. The same can achieved in the JS world where everything is possible, every prototype can be hacked and it can be also type-safe.
15+
16+
### The Problem
17+
18+
The main problem in short that extending another module is _not officially supported_ by Typescript - however the type system can be hacked like _it was_ in FuryStack and as you can see in the following example:
19+
20+
```ts
21+
import { Injector } from '@furystack/inject/dist/injector';
22+
23+
declare module '@furystack/inject/dist/injector' {
24+
export interface Injector {
25+
/**
26+
* returns the current authorization status from the identity context
27+
*/
28+
isAuthorized: (...roles: string[]) => Promise<boolean>;
29+
}
30+
}
31+
32+
Injector.prototype.isAuthorized = async function (...roles) {
33+
return this.getInstance(IdentityContext).isAuthorized(...roles);
34+
};
35+
36+
/** ...and the usage */
37+
38+
import '../path-to-my-extension';
39+
40+
const result = await injector.isAuthorized('admin');
41+
```
42+
43+
...well, it works but I've ran into unexpected issues with conflicting import declarations and overrides. The problems appeared random, but somewhat based on the running context (ts-node, jest, browser) and it started to block dependency upgrades...
44+
45+
### How it works now
46+
47+
The extensions has been replaced by _helpers_, as you can see in the following example. These helpers are simple shortcuts - you should usually pass the injector (or the related manager class) to them as a parameter.
48+
The imports are clear, as well as the execution path and the types.
49+
50+
```ts
51+
import { isAuthorized } from '@furystack/core';
52+
53+
const result = await isAuthorized(injector, 'admin');
54+
```
55+
56+
For more details, you can check out [this](https://github.com/furystack/furystack/commit/ba32902dba6bfbf8db4b1cc8a00861151999b71a#diff-45afbc003c3ca2cf0dac19a66d7aed4c4526c3df2ca00942e814970983e4ce84) commit.
232 KB
Loading
1.58 MB
Loading

src/layouts/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { colors } from '../styles/colors';
1010

1111
interface IndexProps {
1212
className?: string;
13+
children?: React.ReactNode;
1314
}
1415

1516
const IndexLayout: React.FC<IndexProps> = props => {

0 commit comments

Comments
 (0)