Skip to content

Commit

Permalink
docs: add example for different map types in TypeScript generator (#1758
Browse files Browse the repository at this point in the history
)
  • Loading branch information
akkshitgupta authored Feb 1, 2024
1 parent 12ba171 commit e401f0f
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Below is a list of additional options available for a given generator.
| Option | Type | Description | Default value |
|---|---|---|---|
| `renderTypes` | Boolean | Render signature for types. | `true` |
| `mapType` | String | It indicates which mapping type should be rendered for the `object` type. Its value can be one of `map`, `record` or `indexedObject`. | `map` |
| `modelType` | String | It indicates which model type should be rendered for the `object` type. Its value can be either `interface` or `class`. | `class` |
| `enumType` | String | It indicates which type should be rendered for the `enum` type. Its value can be either `union` or `enum`. | `enum` |
| `namingConvention` | Object | Options for naming conventions. | - |
Expand Down
24 changes: 24 additions & 0 deletions docs/languages/TypeScript.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ There are special use-cases that each language supports; this document pertains
<!-- toc -->

- [Generate an interface instead of classes](#generate-an-interface-instead-of-classes)
- [Generate different `mapType`s for an `object` type](#generate-different-maptypes-for-an-object)
- [Generate union types instead of enums](#generate-union-types-instead-of-enums)
- [Generate serializer and deserializer functionality](#generate-serializer-and-deserializer-functionality)
* [To and from JSON](#to-and-from-json)
Expand All @@ -27,6 +28,29 @@ Sometimes you don't care about classes, but rather have interfaces generated. Th

Check out this [example out for a live demonstration](../../examples/typescript-interface).

## Generate different `mapType`s for an `object`

Typescript offers different `mapType`s which can simplify the use based on the needs. This behavior can be changed through the [`mapType` configuration](https://github.com/asyncapi/modelina/blob/master/docs/generators.md#typescript).

- Use `map` when you need a dynamic collection of key-value pairs with built-in methods for manipulation.
- Use `record` when you want to define an object with specific keys and their corresponding value types.
- Use `indexedObject` (or an interface with index signature) for a more generic approach when working with objects with dynamic keys.

An example of the generated code can be seen below:

```ts
// mapType = indexedObject
private _person?: { [name: string]: any };

// mapType = map
private _person?: Map<string, any>;

// mapType = record
private _person?: Record<string, any>;
```

Also, check out this [example for a live demonstration](../../examples/typescript-change-map-type).

## Generate union types instead of enums

Typescript offers union types which can simplify the use as no keywords are needed and the values can be set directly. This behavior can be changed through the [modelType configuration](https://github.com/asyncapi/modelina/blob/master/docs/generators.md#typescript). An example of the generated code can be seen below:
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ These are all specific examples only relevant to the C# generator:
### TypeScript
These are all specific examples only relevant to the TypeScript generator:

- [typescript-change-map-type](./typescript-change-map-type) - A basic example showing the use of `mapType` options.
- [generate-typescript-models](./generate-typescript-models) - A basic example to generate TypeScript data models
- [typescript-interface](./typescript-interface) - A basic TypeScript generator that outputs interfaces.
- [typescript-enum-type](./typescript-enum-type) - A basic example of how to use Modelina can output different types of enums in TypeScript.
Expand Down
17 changes: 17 additions & 0 deletions examples/typescript-change-map-type/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TypeScript Map Types

A basic example showing the use of `mapType` options.

## How to run this example

Run this example using:

```sh
npm i && npm run start
```

If you are on Windows, use the `start:windows` script instead:

```sh
npm i && npm run start:windows
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should be able to render correct map type based on options and should log expected output to console 1`] = `
"// Generator output as indexedObject
class Root {
private _person?: { [name: string]: any };
constructor(input: {
person?: { [name: string]: any },
}) {
this._person = input.person;
}
get person(): { [name: string]: any } | undefined { return this._person; }
set person(person: { [name: string]: any } | undefined) { this._person = person; }
}
// Generator output as Map
class Root {
private _person?: Map<string, any>;
constructor(input: {
person?: Map<string, any>,
}) {
this._person = input.person;
}
get person(): Map<string, any> | undefined { return this._person; }
set person(person: Map<string, any> | undefined) { this._person = person; }
}
// Generator output as Record
class Root {
private _person?: Record<string, any>;
constructor(input: {
person?: Record<string, any>,
}) {
this._person = input.person;
}
get person(): Record<string, any> | undefined { return this._person; }
set person(person: Record<string, any> | undefined) { this._person = person; }
}"
`;
15 changes: 15 additions & 0 deletions examples/typescript-change-map-type/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
return;
});
import { generate } from './index';

describe('Should be able to render correct map type based on options', () => {
afterAll(() => {
jest.restoreAllMocks();
});
test('and should log expected output to console', async (): Promise<void> => {
await generate();
expect(spy.mock.calls.length).toEqual(6);
expect(spy.mock.calls.join('\n')).toMatchSnapshot();
});
});
50 changes: 50 additions & 0 deletions examples/typescript-change-map-type/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { TypeScriptGenerator } from '../../src';

const generatorIndexedObject = new TypeScriptGenerator({
mapType: 'indexedObject'
});
const generatorMap = new TypeScriptGenerator({ mapType: 'map' });
const generatorRecord = new TypeScriptGenerator({ mapType: 'record' });

const jsonSchemaDraft7 = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
additionalProperties: false,
properties: {
person: {
type: 'object',
personName: { type: 'string' },
email: {
type: 'string',
format: 'email'
},
isStudent: { type: 'boolean' },
age: { type: 'number' }
}
}
};

export async function generate(): Promise<void> {
console.log('// Generator output as indexedObject');
const modelsIndexedObject =
await generatorIndexedObject.generate(jsonSchemaDraft7);
for (const model of modelsIndexedObject) {
console.log(model.result);
}

console.log('// Generator output as Map');
const modelsMap = await generatorMap.generate(jsonSchemaDraft7);
for (const model of modelsMap) {
console.log(model.result);
}

console.log('// Generator output as Record');
const modelsRecord = await generatorRecord.generate(jsonSchemaDraft7);
for (const model of modelsRecord) {
console.log(model.result);
}
}

if (require.main === module) {
generate();
}
10 changes: 10 additions & 0 deletions examples/typescript-change-map-type/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions examples/typescript-change-map-type/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"config": {
"example_name": "typescript-change-map-type"
},
"scripts": {
"install": "cd ../.. && npm i",
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts",
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts",
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts",
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts"
}
}

0 comments on commit e401f0f

Please sign in to comment.