{"id":13698404,"url":"https://github.com/jsdoctypeparser/jsdoctypeparser","last_synced_at":"2025-05-04T03:31:23.000Z","repository":{"id":7849508,"uuid":"9221395","full_name":"jsdoctypeparser/jsdoctypeparser","owner":"jsdoctypeparser","description":"Parser module for JsDoc or Closure Compiler format type-annotation.","archived":false,"fork":false,"pushed_at":"2023-03-04T02:57:15.000Z","size":5522,"stargazers_count":54,"open_issues_count":20,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-22T18:12:20.418Z","etag":null,"topics":["javascript","jsdoc","parser"],"latest_commit_sha":null,"homepage":"https://jsdoctypeparser.github.io/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsdoctypeparser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-MIT.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-04-04T15:33:07.000Z","updated_at":"2024-02-13T22:54:48.000Z","dependencies_parsed_at":"2024-06-18T13:44:11.814Z","dependency_job_id":"b1cfaf53-5340-4917-b734-a888d8af21e3","html_url":"https://github.com/jsdoctypeparser/jsdoctypeparser","commit_stats":{"total_commits":386,"total_committers":11,"mean_commits":35.09090909090909,"dds":0.6191709844559585,"last_synced_commit":"5166cc4ac8f1ccfac0d32ec4d2957c58642f2beb"},"previous_names":["kuniwak/jsdoctypeparser"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdoctypeparser%2Fjsdoctypeparser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdoctypeparser%2Fjsdoctypeparser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdoctypeparser%2Fjsdoctypeparser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdoctypeparser%2Fjsdoctypeparser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsdoctypeparser","download_url":"https://codeload.github.com/jsdoctypeparser/jsdoctypeparser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252215971,"owners_count":21713071,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","jsdoc","parser"],"created_at":"2024-08-02T19:00:45.677Z","updated_at":"2025-05-04T03:31:20.935Z","avatar_url":"https://github.com/jsdoctypeparser.png","language":"JavaScript","funding_links":[],"categories":["Parsing and Stringifying"],"sub_categories":["Type parsing"],"readme":"# jsdoctypeparser\n\n[![NPM version](https://badge.fury.io/js/jsdoctypeparser.svg)](http://badge.fury.io/js/jsdoctypeparser) [![Node.js CI status](https://github.com/jsdoctypeparser/jsdoctypeparser.git/workflows/Node.js%20CI/badge.svg)](https://github.com/jsdoctypeparser/jsdoctypeparser.git/actions) [![npm](https://img.shields.io/npm/v/jsdoctypeparser.svg)](https://www.npmjs.com/package/jsdoctypeparser)\n\nThe parser can parse:\n\n* [JSDoc type expressions](https://jsdoc.app/tags-type.html)\n  * `foo.bar`, `String[]`\n* [Closure Compiler type expressions](https://developers.google.com/closure/compiler/docs/js-for-compiler)\n  * `Array\u003cstring\u003e`, `function(arg1, arg2): ret`\n* [some Typescript types](https://github.com/Microsoft/TypeScript)\n  * `(x: number) =\u003e string`, `typeof x`, `import(\"./some-module\")`, `T \u0026 U`\n* Complex type expressions\n  * `Array\u003cArray\u003cstring\u003e\u003e`, `function(function(Function))`\n\n## Live demo\n\nThe [live demo](https://jsdoctypeparser.github.io) is available.\n\n## Usage (Programmatic)\n\n### Parsing\n\n```javascript\nconst {parse} = require('jsdoctypeparser');\n\nconst ast = parse('Array\u003cMyClass\u003e');\n```\n\nThe `ast` becomes:\n\n```json\n{\n  \"type\": \"GENERIC\",\n  \"subject\": {\n    \"type\": \"NAME\",\n    \"name\": \"Array\"\n  },\n  \"objects\": [\n    {\n      \"type\": \"NAME\",\n      \"name\": \"MyClass\"\n    }\n  ],\n  \"meta\": {\n    \"syntax\": \"ANGLE_BRACKET\"\n  }\n}\n```\n\nSee the [AST specifications](https://github.com/Kuniwak/jsdoctypeparser/blob/update-readme/README.md#ast-specifications).\n\n### Publishing\n\nWe can stringify the AST nodes by using `publish`.\n\n```javascript\nconst {publish} = require('jsdoctypeparser');\n\nconst ast = {\n  type: 'GENERIC',\n  subject: {\n    type: 'NAME',\n    name: 'Array'\n  },\n  objects: [\n    {\n      type: 'NAME',\n      name: 'MyClass'\n    }\n  ]\n};\n\nconst string = publish(ast);\n```\n\nThe `string` becomes:\n\n```json\n\"Array\u003cMyClass\u003e\"\n```\n\n#### Custom publishing\n\nWe can change the stringification strategy by using the 2nd parameter of `publish(node, publisher)`.\nThe `publisher` MUST have handlers for all node types (see `lib/NodeType.js`).\n\nAnd we can override default behavior by using `createDefaultPublisher`.\n\n```javascript\nconst {publish, createDefaultPublisher} = require('jsdoctypeparser');\n\nconst ast = {\n  type: 'NAME',\n  name: 'MyClass',\n};\n\nconst customPublisher = createDefaultPublisher();\ncustomPublisher.NAME = (node, pub) =\u003e\n  `\u003ca href=\"./types/${node.name}.html\"\u003e${node.name}\u003c/a\u003e`;\n\nconst string = publish(ast, customPublisher);\n```\n\nThe `string` becomes:\n\n```html\n\u003ca href=\"./types/MyClass.html\"\u003eMyClass\u003c/a\u003e\n```\n\n### Traversing\n\nWe can traverse the AST by using `traverse`.\nThis function takes 3 parameters (a node and an onEnter handler, an onLeave handler).\nThe handlers take a visiting node.\n\n```javascript\nconst {parse, traverse} = require('jsdoctypeparser');\nconst ast = parse('Array\u003c{ key1: function(), key2: A.B.C }\u003e');\n\nfunction onEnter(node, parentName, parentNode) {\n  console.log('enter', node.type, parentName, parentNode.type);\n}\n\nfunction onLeave(node, parentName, parentNode) {\n  console.log('leave', node.type, parentName, parentNode.type);\n}\n\ntraverse(ast, onEnter, onLeave);\n```\n\nThe output will be:\n\n```\nenter GENERIC null null\nenter NAME subject GENERIC\nleave NAME subject GENERIC\nenter RECORD objects GENERIC\nenter RECORD_ENTRY entries RECORD\nenter FUNCTION value RECORD_ENTRY\nleave FUNCTION value RECORD_ENTRY\nleave RECORD_ENTRY entries RECORD\nenter RECORD_ENTRY entries RECORD\nenter MEMBER value RECORD_ENTRY\nenter MEMBER owner MEMBER\nenter NAME owner MEMBER\nleave NAME owner MEMBER\nleave MEMBER owner MEMBER\nleave MEMBER value RECORD_ENTRY\nleave RECORD_ENTRY entries RECORD\nleave RECORD objects GENERIC\nleave GENERIC null null\n```\n\n## AST Specifications\n\n### `NAME`\n\nExample:\n\n```javascript\n/**\n * @type {name}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"NAME\",\n  \"name\": string\n}\n```\n\n### `MEMBER`\n\nExample:\n\n```javascript\n/**\n * @type {owner.name}\n * @type {superOwner.owner.name}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"MEMBER\",\n  \"name\": string,\n  \"quoteStyle\": \"none\",\n  \"owner\": node,\n  \"hasEventPrefix\": boolean\n}\n```\n\n### `INNER_MEMBER`\n\nExample:\n\n```javascript\n/**\n * @type {owner~name}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"INNER_MEMBER\",\n  \"name\": string,\n  \"quoteStyle\": \"none\",\n  \"owner\": node,\n  \"hasEventPrefix\": boolean\n}\n```\n\n### `INSTANCE_MEMBER`\n\nExample:\n\n```javascript\n/**\n * @type {owner#name}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"INSTANCE_MEMBER\",\n  \"name\": string,\n  \"quoteStyle\": \"none\",\n  \"owner\": node,\n  \"hasEventPrefix\": boolean\n}\n```\n\n### `UNION`\n\nExample:\n\n```javascript\n/**\n * @type {left|right}\n * @type {(left|right)}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"UNION\",\n  \"left\": node,\n  \"right\": node\n}\n```\n\n### `INTERSECTION`\n\nExample:\n\n```javascript\n/**\n * @type {left\u0026right}\n * @type {(left\u0026right)}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"INTERSECTION\",\n  \"left\": node,\n  \"right\": node\n}\n```\n\n### `RECORD`\n\nExample:\n\n```javascript\n/**\n * @type {{}}\n * @type {{ key: value }}\n * @type {{ key: value, anyKey }}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"RECORD\",\n  \"entries\": [\n    recordEntryNode,\n    recordEntryNode,\n    ...\n  ]\n}\n```\n\n### `RECORD_ENTRY`\n\nStructure:\n\n```javascript\n{\n  \"type\": \"RECORD_ENTRY\",\n  \"key\": string,\n  \"value\": node (or null)\n}\n```\n\n### `GENERIC`\n\nExample:\n\n```javascript\n/**\n * @type {Subject\u003cObject, Object\u003e}\n * @type {Object[]}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"GENERIC\",\n  \"subject\": node,\n  \"objects\": [\n    node,\n    node,\n    ...\n  ],\n  \"meta\": {\n    \"syntax\": (\"ANGLE_BRACKET\" or \"ANGLE_BRACKET_WITH_DOT\" or \"SQUARE_BRACKET\")\n  }\n}\n```\n\n### `FUNCTION`\n\nExample:\n\n```javascript\n/**\n * @type {function()}\n * @type {function(param, param): return}\n * @type {function(this: Context)}\n * @type {function(new: Class)}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"FUNCTION\",\n  \"params\": [\n    node,\n    node,\n    ...\n  ],\n  \"returns\": node (or null),\n  \"new\": node (or null),\n  \"this\": node (or null)\n}\n```\n\n### `OPTIONAL`\n\nExample:\n\n```javascript\n/**\n * @type {Optional=}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"OPTIONAL\",\n  \"value\": node,\n  \"meta\": {\n    \"syntax\": \"SUFFIX_EQUALS_SIGN\"\n  }\n}\n```\n\n### `NULLABLE`\n\nExample:\n\n```javascript\n/**\n * @type {?Nullable}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"NULLABLE\",\n  \"value\": node,\n  \"meta\": {\n    \"syntax\": (\"PREFIX_QUESTION_MARK\" or \"SUFFIX_QUESTION_MARK\")\n  }\n}\n```\n\n### `NOT_NULLABLE`\n\nExample:\n\n```javascript\n/**\n * @type {!NotNullable}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"NOT_NULLABLE\",\n  \"value\": node,\n  \"meta\": {\n    \"syntax\": (\"PREFIX_BANG\" or \"SUFFIX_BANG\")\n  }\n}\n```\n\n### `VARIADIC`\n\nExample:\n\n```javascript\n/**\n * @type {...Variadic}\n * @type {Variadic...}\n * @type {...}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"VARIADIC\",\n  \"value\": node (or null),\n  \"meta\": {\n    \"syntax\": (\"PREFIX_DOTS\" or \"SUFFIX_DOTS\" or \"ONLY_DOTS\")\n  }\n}\n```\n\n### `MODULE`\n\nExample:\n\n```javascript\n/**\n * @type {module:path/to/file.Module}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"MODULE\",\n  \"value\": node\n}\n```\n\n### `FILE_PATH`\n\nExample:\n\n```javascript\n/**\n * @type {module:path/to/file.Module}\n *               ^^^^^^^^^^^^\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"FILE_PATH\",\n  \"path\": string\n}\n```\n\n### `EXTERNAL`\n\nExample:\n\n```javascript\n/**\n * @type {external:External}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"EXTERNAL\",\n  \"value\": node\n}\n```\n\n### `STRING_VALUE`\n\nExample:\n\n```javascript\n/**\n * @type {\"abc\"}\n * @type {\"can\\\"escape\"}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"STRING_VALUE\",\n  \"quoteStyle\": \"double\",\n  \"string\": string\n}\n```\n\n### `NUMBER_VALUE`\n\nExample:\n\n```javascript\n/**\n * @type {123}\n * @type {0b11}\n * @type {0o77}\n * @type {0xff}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"NUMBER_VALUE\",\n  \"number\": string\n}\n```\n\n### `ANY`\n\nExample:\n\n```javascript\n/**\n * @type {*}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"ANY\"\n}\n```\n\n### `UNKNOWN`\n\nExample:\n\n```javascript\n/**\n * @type {?}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"UNKNOWN\"\n}\n```\n\n### `PARENTHESIS`\n\nExample:\n\n```javascript\n/**\n * @type {(Foo)}\n */\n```\n\nStructure:\n\n```javascript\n{\n  \"type\": \"PARENTHESIS\",\n  \"value\": node\n}\n```\n\n### Others\n\nWe can use a parenthesis to change operator orders.\n\n```javascript\n/**\n * @type {(module:path/to/file.js).foo}\n */\n```\n\n## Usage (CLI)\n\nTo parse a type into a JSON structure, you may pass a string argument\ncontaining the structure to parse (with the JSON results equivalent to the\nparsing example above):\n\n```\njsdoctypeparser 'Array\u003cMyClass\u003e'\n```\n\nNote: There is no need to prefix the path to the `jsdoctypeparser` binary,\ne.g., with `./node_modules/.bin/` when you are running within one of the\n`package.json` `scripts` or if you have installed the package globally.\n\n## License\n\n[This script is licensed under the MIT](./LICENSE-MIT.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdoctypeparser%2Fjsdoctypeparser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsdoctypeparser%2Fjsdoctypeparser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdoctypeparser%2Fjsdoctypeparser/lists"}