{"id":41489226,"url":"https://github.com/eggjs/egg-ts-helper","last_synced_at":"2026-01-23T18:16:21.763Z","repository":{"id":30337669,"uuid":"123697284","full_name":"eggjs/egg-ts-helper","owner":"eggjs","description":"🍳 Generate TypeScript definition files(d.ts) for Egg","archived":false,"fork":false,"pushed_at":"2025-10-05T19:17:26.000Z","size":594,"stargazers_count":161,"open_issues_count":13,"forks_count":31,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-15T16:30:41.631Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/eggjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-03-03T14:04:35.000Z","updated_at":"2025-10-05T19:17:29.000Z","dependencies_parsed_at":"2024-11-06T08:33:30.820Z","dependency_job_id":"0ff50f85-9dfd-40fc-91e3-c337b50acc09","html_url":"https://github.com/eggjs/egg-ts-helper","commit_stats":{"total_commits":324,"total_committers":17,"mean_commits":"19.058823529411764","dds":0.3827160493827161,"last_synced_commit":"f396e5f93fff751ba768c5740cc4ad0cf6e0cf13"},"previous_names":[],"tags_count":106,"template":false,"template_full_name":null,"purl":"pkg:github/eggjs/egg-ts-helper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eggjs%2Fegg-ts-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eggjs%2Fegg-ts-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eggjs%2Fegg-ts-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eggjs%2Fegg-ts-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eggjs","download_url":"https://codeload.github.com/eggjs/egg-ts-helper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eggjs%2Fegg-ts-helper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28697428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T17:25:48.045Z","status":"ssl_error","status_checked_at":"2026-01-23T17:25:47.153Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-23T18:16:20.959Z","updated_at":"2026-01-23T18:16:21.755Z","avatar_url":"https://github.com/eggjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# egg-ts-helper\n\n[![NPM version][npm-image]][npm-url]\n[![Node.js CI](https://github.com/eggjs/egg-ts-helper/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/egg-ts-helper/actions/workflows/nodejs.yml)\n[![Package Quality](http://npm.packagequality.com/shield/egg-ts-helper.svg)](http://packagequality.com/#?package=egg-ts-helper)\n[![Test coverage][codecov-image]][codecov-url]\n[![NPM download][download-image]][download-url]\n\n[npm-image]: https://img.shields.io/npm/v/egg-ts-helper.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/egg-ts-helper\n[codecov-image]: https://codecov.io/gh/whxaxes/egg-ts-helper/branch/master/graph/badge.svg\n[codecov-url]: https://codecov.io/gh/whxaxes/egg-ts-helper\n[download-image]: https://img.shields.io/npm/dm/egg-ts-helper.svg?style=flat-square\n[download-url]: https://npmjs.org/package/egg-ts-helper\n\nA simple tool for creating `d.ts` in [egg](https://eggjs.org) application. Injecting `controller, proxy, service, etc.` to definition type of egg ( such as `Context` `Application` etc. ) by [Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html), and making IntelliSense works in both egg-js and egg-ts.\n\n## Install\n\nopen your application and install.\n\n```bash\nnpm i egg-ts-helper --save-dev\n```\n\n## QuickStart\n\nOpen your egg application, executing ets by [npx](https://github.com/zkat/npx)\n\n```bash\nnpx ets\n```\n\nWatching files by `-w` flag.\n\n```bash\nnpx ets -w\n```\n\n`egg-ts-helper` has build-in in `egg-bin`, You can easily to use it by\n\n```bash\negg-bin dev --dts\n```\n\nor add configuration `egg.declarations` in `package.json`\n\n## CLI\n\n```\n$ ets -h\n\n  Usage: bin [commands] [options]\n\n  Options:\n    -v, --version           output the version number\n    -w, --watch             Watching files, d.ts would recreated while file changed\n    -c, --cwd [path]        Egg application base dir (default: process.cwd)\n    -C, --config [path]     Configuration file, The argument can be a file path to a valid JSON/JS configuration file.（default: {cwd}/tshelper\n    -o, --oneForAll [path]  Create a d.ts import all types (default: typings/ets.d.ts)\n    -s, --silent            Running without output\n    -i, --ignore [dirs]     Ignore generator, your can ignore multiple dirs with comma like: -i controller,service\n    -e, --enabled [dirs]    Enable generator, your can enable multiple dirs with comma like: -e proxy,other\n    -E, --extra [json]      Extra config, the value should be json string\n    -h, --help              output usage information\n\n  Commands:\n    clean                   Clean js file while it has the same name ts/tsx file\n    init \u003ctype\u003e             Init egg-ts-helper in your existing project\n```\n\n## Configuration\n\n| name | type | default | description |\n| --- | --- | --- | --- |\n| cwd | `string` | process.cwd | egg application base dir |\n| typings | `string` | {cwd}/typings | typings dir |\n| caseStyle | `string` `Function` | lower | egg case style(lower,upper,camel) or `(filename) =\u003e {return 'YOUR_CASE'}`|\n| silent | `boolean` | false | ignore logging |\n| watch | `boolean` | false | watch file change or not, default to `true` in `register`  |\n| watchOptions | `object` | undefined | chokidar [options](https://github.com/paulmillr/chokidar#api) |\n| autoRemoveJs | `boolean` | true | auto remove same name js on startup |\n| configFile | `string` | {cwd}/tshelper.(js|json) | configure file path |\n| generatorConfig | `object` | | generator configuration( watchDirs has been deprecated ) |\n\nYou can configure the options above in `./tshelper.js` `./tshelper.json` or `package.json`.\n\nIn `tshelper.js`\n\n```js\n// {cwd}/tshelper.js\n\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      enabled: true,\n      generator: \"function\",\n      interfaceHandle: \"InstanceType\u003c{{ 0 }}\u003e\"\n    },\n  }\n}\n```\n\nIn `tshelper.json`\n\n```json\n// {cwd}/tshelper.json\n\n{\n  \"generatorConfig\": {\n    \"model\": {\n      \"enabled\": true,\n      \"generator\": \"function\",\n      \"interfaceHandle\": \"InstanceType\u003c{{ 0 }}\u003e\"\n    },\n  }\n}\n```\n\nIn `package.json`\n\n```json\n// {cwd}/package.json\n\n{\n  \"egg\": {\n    \"framework\": \"egg\",\n    \"tsHelper\": {\n      \"generatorConfig\": {\n        \"model\": {\n          \"enabled\": true,\n          \"generator\": \"function\",\n          \"interfaceHandle\": \"InstanceType\u003c{{ 0 }}\u003e\"\n        }\n      }\n    }\n  }\n}\n```\n\nor use `dot-prop`\n\n```json\n// {cwd}/package.json\n\n{\n  \"egg\": {\n    \"framework\": \"egg\",\n    \"tsHelper\": {\n      \"generatorConfig.model\": {\n        \"enabled\": true,\n        \"generator\": \"function\",\n        \"interfaceHandle\": \"InstanceType\u003c{{ 0 }}\u003e\"\n      }\n    }\n  }\n}\n```\n\nAlso you can pass options by env ( support since 1.22.0 )\n\n- `ETS_CWD`: cwd\n- `ETS_FRAMEWORK`: framework\n- `ETS_TYPINGS`: typings\n- `ETS_CASE_STYLE`: caseStyle\n- `ETS_AUTO_REMOVE_JS`: autoRemoveJs\n- `ETS_THROTTLE`: throttle\n- `ETS_WATCH`: watch\n- `ETS_SILENT`: silent\n- `ETS_CONFIG_FILE`: configFile\n\n## Custom Loader\n\n\u003e Support since 1.24.0\n\n`egg-ts-helper` support customLoader configuration of egg. see \u003chttps://github.com/eggjs/egg/issues/3480\u003e\n\nConfigure in `config.default.ts`\n\n```typescript\n'use strict';\n\nimport { EggAppConfig, PowerPartial } from 'egg';\n\nexport default function(appInfo: EggAppConfig) {\n  const config = {} as PowerPartial\u003cEggAppConfig\u003e;\n\n  config.keys = appInfo.name + '123123';\n\n  config.customLoader = {\n    model: {\n      directory: 'app/model',\n      inject: 'app',\n      caseStyle: 'upper',\n    },\n  };\n\n  return {\n    ...config as {},\n    ...bizConfig,\n  };\n}\n```\n\n`egg-ts-helper` will auto create the d.ts for files under `app/model`\n\n```typescript\n// This file is created by egg-ts-helper@1.24.1\n// Do not modify this file!!!!!!!!!\n\nimport 'egg';\ntype AutoInstanceType\u003cT, U = T extends (...args: any[]) =\u003e any ? ReturnType\u003cT\u003e : T\u003e = U extends { new (...args: any[]): any } ? InstanceType\u003cU\u003e : U;\nimport ExportCastle from '../../../app/model/Castle';\nimport ExportUser from '../../../app/model/User';\n\ndeclare module 'egg' {\n  interface Application {\n    model: T_custom_model;\n  }\n\n  interface T_custom_model {\n    Castle: AutoInstanceType\u003ctypeof ExportCastle\u003e;\n    User: AutoInstanceType\u003ctypeof ExportUser\u003e;\n  }\n}\n```\n\nAnd you can easily to use it in your code.\n\n![image](https://user-images.githubusercontent.com/5856440/54109111-b4848b80-4418-11e9-9da5-77b342f7f814.png)\n\n## Generator\n\nIf you are using `loader.loadToApp` or `loader.loadToContext` to load the instance, you should use generator config.\n\n### Example\n\nCreating `d.ts` for files under `app/model`. You should add config `generatorConfig.model` in your config file.\n\n```typescript\n// ./tshelper.js\n\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      directory: 'app/model', // files directory.\n      // pattern: '**/*.(ts|js)', // glob pattern, default is **/*.(ts|js). it doesn't need to configure normally.\n      // ignore: '', // ignore glob pattern, default to empty.\n      generator: 'class', // generator name, eg: class、auto、function、object\n      interface: 'IModel',  // interface name\n      declareTo: 'Context.model', // declare to this interface\n      // watch: true, // whether need to watch files\n      // caseStyle: 'upper', // caseStyle for loader\n      // interfaceHandle: val =\u003e `ReturnType\u003ctypeof ${val}\u003e`, // interfaceHandle\n      // trigger: ['add', 'unlink'], // recreate d.ts when receive these events, all events: ['add', 'unlink', 'change']\n    }\n  }\n}\n```\n\nThe configuration can create d.ts as below.\n\n\u003e Attention, The type will merge into egg without any pre handling if the generator field is `class`, If you dont know how it works, just using `generator: 'auto'` instead.\n\n```typescript\nimport Station from '../../../app/model/station';// \u003c-- find all files under app/model and import then.\n\ndeclare module 'egg' {\n  interface Context { // \u003c-- Context is reading from `declareTo`\n    model: IModel; // \u003c-- IModel is reading from `interface`, It will create a random interface if this field is empty\n  }\n\n  interface IModel { // \u003c-- The same as above.\n    Station: Station; // \u003c-- Merging `Station` to IModel so we can use `ctx.model.Station` in code.\n  }\n}\n```\n\n### Effect of different options\n\n#### interface `string`\n\n`interface` set to `IOther`.\n\n```typescript\ninterface IOther {\n  Station: Station;\n}\n```\n\nIt will use random interface if `interface` is not set.\n\n```typescript\ninterface T100 {\n  Station: Station;\n}\n```\n\nAttentions: Must set `declareTo` if `interface` is not set.\n\n#### generator `string`\n\nThe name of generator, available value is `class` `function` `object` `auto`.\n\n**`generator: 'class'`**\n\nthe types created by `class` generator as below\n\n```typescript\ninterface IModel {\n  Station: Station;\n}\n```\n\nIt's suitable for module wrote like this\n\n```typescript\nexport default class XXXController extends Controller { }\n```\n\n**`generator: 'function'`** ( Support since `1.16.0` )\n\nthe types created by `function` generator as below\n\n```typescript\ninterface IModel {\n  Station: ReturnType\u003ctypeof Station\u003e; // Using ReturnType to get return type of function.\n}\n```\n\nIt's suitable for module like this\n\n```typescript\nexport default () =\u003e {\n  return {};\n}\n```\n\n**`generator: 'object'`** ( Support since `1.16.0` )\n\nthe types created by `object` generator as below.\n\n```typescript\ninterface IModel {\n  Station: typeof Station;\n}\n```\n\nIt's suitable for module like this\n\n```typescript\nexport default {}\n```\n\n**`generator: 'auto'`** ( Support since `1.19.0` )\n\nthe types created by `auto` generator as below. It will check types automatically.\n\n```typescript\ntype AutoInstanceType\u003cT, U = T extends (...args: any[]) =\u003e any ? ReturnType\u003cT\u003e : T\u003e = U extends { new (...args: any[]): any } ? InstanceType\u003cU\u003e : U;\n\ninterface IModel {\n  Station: AutoInstanceType\u003ctypeof Station\u003e;\n}\n```\n\nIt's suitable for every module in above.\n\n#### interfaceHandle `function|string`\n\nIf you cannot find suitable generator in above, you can config the type by this field.\n\n```js\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      ...\n\n      interfaceHandle: val =\u003e `${val} \u0026 { [key: string]: any }`,\n    }\n  }\n}\n```\n\nThe generated typings.\n\n```typescript\ninterface IModel {\n  Station: Station \u0026 { [key: string]: any };\n}\n```\n\nThe type of `interfaceHandle` can be `string` ( Support since `1.18.0` )\n\n```js\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      ...\n\n      interfaceHandle: '{{ 0 }} \u0026 { [key: string]: any }',\n    }\n  }\n}\n```\n\nThe generated typings are the same as above. `{{ 0 }}` means the first argument in function.\n\n#### caseStyle `function|string`\n\n`caseStyle` can set to `lower`、`upper`、`camel` or function\n\n#### declareTo `string`\n\nDeclaring interface to definition of egg. ( Support since `1.15.0` )\n\n`declareTo` set to `Context.model` , and you can get intellisense by `ctx.model.xxx`\n\n```typescript\nimport Station from '../../../app/model/station';\n\ndeclare module 'egg' {\n  interface Context {\n    model: IModel;\n  }\n\n  interface IModel {\n    Station: Station;\n  }\n}\n```\n\n`declareTo` set to `Application.model.subModel`, and you can get intellisense by `app.model.subModel.xxx`\n\n```typescript\nimport Station from '../../../app/model/station';\n\ndeclare module 'egg' {\n  interface Application {\n    model: {\n      subModel: IModel;\n    }\n  }\n\n  interface IModel {\n    Station: Station;\n  }\n}\n```\n\n### Defining custom generator\n\n```javascript\n// ./tshelper.js\n\n// custom generator\nfunction myGenerator(config, baseConfig) {\n  // config.dir       dir\n  // config.dtsDir    d.ts dir\n  // config.file      changed file\n  // config.fileList  file list\n  console.info(config);\n  console.info(baseConfig);\n\n  // return type can be object or array { dist: string; content: string } | Array\u003c{ dist: string; content: string }\u003e\n  // egg-ts-helper will remove dist file when content is undefined.\n  return {\n    dist: 'd.ts file url',\n    content: 'd.ts content'\n  }\n}\n\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      directory: 'app/model',\n      generator: myGenerator,\n      trigger: ['add', 'unlink'],\n    }\n  }\n}\n```\n\nor define generator to other js.\n\n```javascript\n// ./my-generator.js\n\nmodule.exports.defaultConfig = {\n  // default watchDir config\n}\n\n// custom generator\nmodule.exports = (config, baseConfig) =\u003e {\n  // config.dir       dir\n  // config.dtsDir    d.ts dir\n  // config.file      changed file\n  // config.fileList  file list\n  console.info(config);\n  console.info(baseConfig);\n\n  // return type can be object or array { dist: string; content: string } | Array\u003c{ dist: string; content: string }\u003e\n  // egg-ts-helper will remove dist file when content is undefined.\n  return {\n    dist: 'd.ts file url',\n    content: 'd.ts content'\n  }\n}\n```\n\nconfigure in `tshelper.js` or `package.json`\n\n```js\n// ./tshelper.js\n\nmodule.exports = {\n  generatorConfig: {\n    model: {\n      directory: 'app/model',\n      generator: './my-generator',\n      trigger: ['add', 'unlink'],\n    }\n  }\n}\n```\n\n## Demo\n\n`egg-ts-helper` can works in both `ts` and `js` egg project.\n\nTS demo: \u003chttps://github.com/whxaxes/egg-boilerplate-d-ts\u003e\n\nJS demo: \u003chttps://github.com/whxaxes/egg-boilerplate-d-js\u003e\n\n## License\n\n[MIT](LICENSE)\n\n## Contributors\n\n[![Contributors](https://contrib.rocks/image?repo=eggjs/tracer)](https://github.com/eggjs/tracer/graphs/contributors)\n\nMade with [contributors-img](https://contrib.rocks).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feggjs%2Fegg-ts-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feggjs%2Fegg-ts-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feggjs%2Fegg-ts-helper/lists"}