forked from finos/morphir-elm
-
Notifications
You must be signed in to change notification settings - Fork 0
Dwinship/typescript/coder and decoder annotations #13
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
Cynical-Optimist
wants to merge
15
commits into
codethink/typescript-codec
Choose a base branch
from
dwinship/typescript/coderAndDecoderAnnotations
base: codethink/typescript-codec
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.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
25e7d2b
Merge pull request #538 from CodethinkLabs/codethink/typescript-codec
AttilaMihaly 2aeb539
Added some docs about the project setup in the contribution guide.
AttilaMihaly 5c5a4d5
Add documentation for TypeScript backend
2022a77
Merge pull request #547 from AttilaMihaly/main
AttilaMihaly 68590f1
Merge pull request #548 from CodethinkLabs/codethink/typescript-docs
AttilaMihaly bc0eebd
Skeleton implementation of multiary decision tree data structure.
AttilaMihaly a2fb6be
Merge pull request #549 from AttilaMihaly/main
AttilaMihaly 392d2ff
TypeScript AST: type annotations on functions
Cynical-Optimist 7b64028
TypeScript AST: add more language features
Cynical-Optimist 4311365
Typescript: prettify codecs.ts
Cynical-Optimist 4171c1b
TypeScript: type annotations for variant decoders
Cynical-Optimist 4852463
TypeScript: type annotations for other decoders
Cynical-Optimist 34ea6f6
TypeScript: annotate encoder functions
Cynical-Optimist c943a4b
TypeScript: change custom type encoder functions
Cynical-Optimist 5ddaabc
TypeScript: remove unused functions from Codecs.ts
Cynical-Optimist 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,131 @@ | ||
| # TypeScript API | ||
|
|
||
| The purpose of this document is describing the TypeScript API generated for Morphir | ||
| models by running `morphir-elm gen --target=TypeScript`. | ||
|
|
||
| ## Generating TypeScript | ||
|
|
||
| Given a model represented in `morphir-ir.json`, you can generate a TypeScript | ||
| representation by running: | ||
|
|
||
| morphir-elm gen --input morphir-ir.json --output ./generated --target=TypeScript | ||
|
|
||
| Note that at present only the types are converted. Data values and functions | ||
| are not. | ||
|
|
||
| You can generate a TypeScript representation of the Morphir IR itself by | ||
| running this in the morphir-elm repo: | ||
|
|
||
| morphir-elm make ./morphir-make --types-only | ||
| morphir-elm gen --input=morphir-ir.json --output=./generated --target=TypeScript | ||
|
|
||
| ## Using the generated types | ||
|
|
||
| The TypeScript backend outputs a top-level module per package, which your own | ||
| code should import. The namespaces correspond with the package and module names | ||
| in the IR. Only namespaces and symbols marked as public will be exported in the | ||
| TypeScript API. | ||
|
|
||
| For example, you can use the `IR` types from the `Morphir` package like this: | ||
|
|
||
| import { Morphir } from './generated/Morphir' | ||
|
|
||
| const myName: Morphir.IR.Name.Name = ["this", "is", "a", "great", "name"] | ||
|
|
||
| Internally the types map to TypeScript type definitions. This is how a Morphir | ||
| IR `Name` would be represented in `generated/morphir/ir/Name.ts`: | ||
|
|
||
| export type Name = Array<string> | ||
|
|
||
| You benefit from all the usual TypeScript type checking. For example, a Path | ||
| must be a list of Name instances, so this example will raise an error: | ||
|
|
||
| import { Morphir } from './generated/Morphir' | ||
|
|
||
| const myName: Morphir.IR.Path.Path = "This is the wrong type." | ||
|
|
||
| You should see this message when compiling: | ||
|
|
||
| test.ts:3:7 - error TS2322: Type 'string' is not assignable to type 'Path'. | ||
|
|
||
| Most Morphir types correspond directly to JavaScript types. The | ||
| [JSON mapping](https://github.com/finos/morphir-elm/blob/main/docs/json-mapping.md) | ||
| gives a useful reference. There are some special cases, which are documented below. | ||
|
|
||
| ### Type mapping details | ||
|
|
||
| #### Dict | ||
|
|
||
| A `Morphir.SDK.Dict.Dict K V` maps to a TypeScript `Map<K,V>`. | ||
|
|
||
| #### Custom types | ||
|
|
||
| We follow the example | ||
| ["Tagged Union Types in TypeScript"](https://mariusschulz.com/blog/tagged-union-types-in-typescript) | ||
| to implement custom types. | ||
|
|
||
| Each type variant is a TypeScript `interface`, with a `kind` and maybe some | ||
| fields. The fields names are defined in the IR, and if you used `morphir-elm` | ||
| make to build the IR then the names will follow the pattern `arg1`, `arg2`, | ||
| `arg3` and so on. | ||
|
|
||
| Constructor functions are provided for these. Here's an example using the | ||
| Morphir IR `Value` custom type, creating an instance of its `Reference` | ||
| variant: | ||
|
|
||
| import { Morphir } from './generated/Morphir' | ||
|
|
||
| const exampleFQName: Morphir.IR.FQName.FQName = [[], [[]], ["excellent", "name"]]; | ||
|
|
||
| type AttrType = []; | ||
| let myReference = new Morphir.IR.Value.Reference<AttrType>([], exampleFQName); | ||
|
|
||
| Calling the constructor function is equivalent to manually constructing an object | ||
| and setting the relevant properties: | ||
|
|
||
| let myReference: Morphir.IR.Value.Reference<AttrType> = { | ||
| kind: "Reference", | ||
| arg1: [], | ||
| arg2: exampleFQName, | ||
| } | ||
|
|
||
| Constructor functions are only provided for custom types. | ||
|
|
||
| #### Type variables | ||
|
|
||
| Morphir's custom types and type aliases can use type variables. These map to | ||
| TypeScript [generics](https://www.typescriptlang.org/docs/handbook/2/generics.html). | ||
|
|
||
| Here's an example using Morphir IR's `AccessControlled` type, which is a type | ||
| alias that maps to a Record. | ||
|
|
||
| import { Morphir } from './generated/Morphir' | ||
|
|
||
| const myAccess = new Morphir.IR.AccessControlled.Public(); | ||
|
|
||
| let myAccessControlled: Morphir.IR.AccessControlled.AccessControlled<String> = { | ||
| access: myAccess, | ||
| value: "I'm a string", | ||
| } | ||
|
|
||
| ## JSON serialization and deserialization | ||
|
|
||
| The generated TypeScript API includes `decode` and `encode` functions for each | ||
| type, used to serialize and deserialize instances of the types according to the | ||
| [standard Morphir JSON mapping](https://github.com/finos/morphir-elm/blob/master/docs/json-mapping.md). | ||
|
|
||
| With the generated Morphir.IR API, this allows you to read entire `morphir-ir.json` files | ||
| into your TypeScript program and create instances of the appropriate types. Here's how you | ||
| might do that: | ||
|
|
||
| import { Morphir } from './generated/Morphir' | ||
|
|
||
| function loadMorphirIR(text) { | ||
| let data = JSON.parse(text); | ||
|
|
||
| if (data['format-version'] != 2) { | ||
| throw "Unsupported morphir-ir.json format"; | ||
| } | ||
|
|
||
| return Morphir.IR.Distribution.decodeDistribution(data['distribution']); | ||
| } |
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.