-
Notifications
You must be signed in to change notification settings - Fork 0
📝 docs(arc 35): methods documentation #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
matdudek
wants to merge
7
commits into
main
Choose a base branch
from
feature/arc-35-methods-documentation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+163
−2
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
3c39e51
:memo: docs: add complex-types section
bfed70d
:memo: docs: add Methods type documentation (sketch)
3744a9f
:memo: docs: add Methods type documentation
e9a1ece
Merge remote-tracking branch 'origin/main' into feature/arc-35-method…
grixu 92b4f3e
:art: style: format
grixu ef5fd24
:pencil2: fix: polish
grixu 8fe0aca
Merge branch 'main' into feature/arc-35-methods-documentation
grixu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Deep Dive into Complex type within lib | ||
|
|
||
| TODO 👷♂️ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| # Methods | ||
|
|
||
| In this section we will explore all nooks and crannies behind methods types. | ||
|
|
||
| ## The Methods type | ||
|
|
||
| ### Why? | ||
|
|
||
| So basically type `Methods` is defined to declare how methods within Entity are built.\ | ||
| It will be an object with keys and values | ||
|
|
||
|
|
||
| ### How? | ||
|
|
||
| ```ts | ||
| export type Methods<TSchema extends EntitySchema> = Record< | ||
| string, // keys | ||
| (this: TSchema, ...args: any[]) => any // values | ||
| > | ||
| ``` | ||
|
|
||
| ::: info EntitySchema | ||
| ```ts | ||
| Record<string, any> | ||
| ``` | ||
| ::: | ||
|
|
||
| It's a `Record` that has keys as strings & methods as values. | ||
|
|
||
| The values part seems to be tricky. It indicates a methods that takes | ||
| - `this` of type `TSchema` as it's first parameter. | ||
| - `..args: any[]` as rest. (It means any number of arguments of any type) | ||
|
|
||
| ::: details Why we indicate `this` of type `TSchema`? | ||
| All methods have `this` inside and we must declare it's type. Without it we would get an `unknown` type instead. | ||
| We assume that all methods in `Entity` are going to have access to data layer. By defining `this: TSchema` we are giving correct type to `this`. This means that `this` inside entity function will be type of data layer and user will be able to use it without errors. | ||
| ::: | ||
|
|
||
| ## Prototype Methods | ||
|
|
||
| ### Why? | ||
|
|
||
| Prototype Methods are default methods inside every entity.\ | ||
| It doesn't matter what Entity we are going to build we will always have this base methods inside. | ||
|
|
||
| ### How? | ||
|
|
||
| It's an `object` with two keys. | ||
|
|
||
| ```ts | ||
| export type PrototypeMethods<TSchema extends EntitySchema> = { | ||
| toObject(): TSchema | ||
| toJson(): string | ||
| } | ||
| ``` | ||
|
Comment on lines
+48
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Zrobiłem update po refactorach |
||
|
|
||
| ## ResolvedMethods | ||
|
|
||
| ### Why? | ||
|
|
||
| This type is a mechanism for ensuring that the user-defined methods for an `EntitySchema` are appropriately augmented and validated based on a set of `PrototypeMethods`. | ||
|
|
||
| ::: info | ||
| When factory function infers `TMethods` without union with undefined it set value of the `TMethods` to `Methods<TSchema>` - which makes it impossible to detect on the type level if the user defined any methods but when we set `TMethods` to `Methods<TSchema> | undefined` it will be possible to detect it. | ||
| ::: | ||
|
|
||
| ### How? | ||
|
|
||
| ```ts | ||
| export type ResolvedMethods< | ||
| TSchema extends EntitySchema, | ||
| TMethods extends Methods<TSchema> | undefined, | ||
| > = ( | ||
| TMethods extends Methods<TSchema> | ||
| ? TMethods extends undefined | ||
| ? "false" | ||
| : "true" | ||
| : 0 | ||
| ) extends "true" | ||
| ? TMethods extends Methods<TSchema> | ||
| ? { | ||
| [Key in Exclude< | ||
| keyof PrototypeMethods<TSchema>, | ||
| keyof TMethods | ||
| >]: PrototypeMethods<TSchema>[Key] | ||
| } & Except<TMethods, "update" | "getIdentifier"> | ||
| : never | ||
| : PrototypeMethods<TSchema> | ||
| ``` | ||
|
|
||
| The `ResolvedMethods` type uses conditional types to perform this check and manipulation. It leverages TypeScript's behavior with union types and conditional types to make these distinctions. 🤯 | ||
|
|
||
| To have a better view we will breakdown `ResolvedMethods` step by step | ||
|
|
||
| #### 1. Generics | ||
|
|
||
| - `TSchema` - which is a data layer for entity, | ||
| - `TMethods` - which is an `object` of user-defined methods or `undefined` | ||
|
|
||
| #### 2. Conditionals for User-Defined Methods | ||
|
|
||
| ```ts | ||
| ( | ||
| TMethods extends Methods<TSchema> | ||
| ? TMethods extends undefined | ||
| ? "false" | ||
| : "true" | ||
| : 0 | ||
| ) | ||
| ``` | ||
| It's a part where type need to check if user defined any methods. Type calculates correct input to proceed. | ||
|
|
||
| This type uses double check if `TMethods` are equal to `Methods` and to `undefined`. | ||
| By this operation we are sure that we talking about non declared `TMethods` by user. | ||
| Why? Because TypeScript can't explicit and clearly tell it's undefined - it uses union | ||
| of undefined and the type used in extends check - so it's `Methods<TSchema> | undefined`. | ||
|
|
||
| When we detect state of not declared `TMethods` we are using string literal type "true" to | ||
| mark it. TypeScript has Distributive Conditional Types mechanism it will check | ||
| union `Methods<TSchema> | undefined` twice, and answer will be `false | 0`. | ||
|
|
||
| Such combination will without any problems rejected from next conditional type check for `"true"` literal. | ||
| It's important here to combine two primitives types, not any other such as undefined or unknown. | ||
|
|
||
| The `0` is kinda random, we need to return anything but `"true"`. | ||
|
|
||
| The calculations will be always an union (Type is running mechanism twice for `Methods<TSchema>` & `undefined`) | ||
| and result will contain `"true"` or `"false"` or `0` | ||
|
|
||
| #### 3. Augmentation of Methods | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prostszym pojęciem jest merge i to bym poszedł niż w Augmentation. ;) |
||
|
|
||
| ```ts | ||
| ... extends "true" | ||
| ? TMethods extends Methods<TSchema> | ||
| ? { | ||
| [Key in Exclude< | ||
| keyof PrototypeMethods<TSchema>, | ||
| keyof TMethods | ||
| >]: PrototypeMethods<TSchema>[Key] | ||
| } & Except<TMethods, "update" | "getIdentifier"> | ||
| : never | ||
| : PrototypeMethods<TSchema> | ||
| ``` | ||
|
|
||
| If Calculations from [Conditionals for User-Defined Methods](#_2-conditionals-for-user-defined-methods) is labeled as `"true"` it means that the user has explicitly defined methods.\ | ||
| Type then checks if the user-defined methods (`TMethods`) are a subset of the prototype methods (`PrototypeMethods<TSchema>`). | ||
| If they are, Type augments the user-defined methods with additional prototype methods, excluding specific keys (`update` and `getIdentifier`). | ||
|
|
||
| If Calculations from [Conditionals for User-Defined Methods](#_2-conditionals-for-user-defined-methods) is labeled as `"false"` (meaning it's not explicitly defined), the type defaults to using the prototype methods (`PrototypeMethods<TSchema>`). | ||
|
|
||
| #### 4. Resulting Type: | ||
|
|
||
| The resulting type is a combination of | ||
| - prototype methods | ||
| - user-defined methods (ensuring that the user-defined methods are properly augmented based on the prototype methods). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To jescze trzeba zupdate-ować