Giter VIP home page Giter VIP logo

egg-ts-helper's Introduction

egg-ts-helper

NPM version Node.js CI Package Quality Test coverage NPM download

A simple tool for creating d.ts in egg application. Injecting controller, proxy, service, etc. to definition type of egg ( such as Context Application etc. ) by Declaration Merging, and making IntelliSense works in both egg-js and egg-ts.

Install

open your application and install.

npm i egg-ts-helper --save-dev

QuickStart

Open your egg application, executing ets by npx

npx ets

Watching files by -w flag.

npx ets -w

egg-ts-helper has build-in in egg-bin, You can easily to use it by

egg-bin dev --dts

or add configuration egg.declarations in package.json

CLI

$ ets -h

  Usage: bin [commands] [options]

  Options:
    -v, --version           output the version number
    -w, --watch             Watching files, d.ts would recreated while file changed
    -c, --cwd [path]        Egg application base dir (default: process.cwd)
    -C, --config [path]     Configuration file, The argument can be a file path to a valid JSON/JS configuration file.(default: {cwd}/tshelper
    -o, --oneForAll [path]  Create a d.ts import all types (default: typings/ets.d.ts)
    -s, --silent            Running without output
    -i, --ignore [dirs]     Ignore generator, your can ignore multiple dirs with comma like: -i controller,service
    -e, --enabled [dirs]    Enable generator, your can enable multiple dirs with comma like: -e proxy,other
    -E, --extra [json]      Extra config, the value should be json string
    -h, --help              output usage information

  Commands:
    clean                   Clean js file while it has the same name ts/tsx file
    init <type>             Init egg-ts-helper in your existing project

Configuration

name type default description
cwd string process.cwd egg application base dir
typings string {cwd}/typings typings dir
caseStyle string Function lower egg case style(lower,upper,camel) or (filename) => {return 'YOUR_CASE'}
silent boolean false ignore logging
watch boolean false watch file change or not, default to true in register
watchOptions object undefined chokidar options
autoRemoveJs boolean true auto remove same name js on startup
configFile string {cwd}/tshelper.(js json)
generatorConfig object generator configuration( watchDirs has been deprecated )

You can configure the options above in ./tshelper.js ./tshelper.json or package.json.

In tshelper.js

// {cwd}/tshelper.js

module.exports = {
  generatorConfig: {
    model: {
      enabled: true,
      generator: "function",
      interfaceHandle: "InstanceType<{{ 0 }}>"
    },
  }
}

In tshelper.json

// {cwd}/tshelper.json

{
  "generatorConfig": {
    "model": {
      "enabled": true,
      "generator": "function",
      "interfaceHandle": "InstanceType<{{ 0 }}>"
    },
  }
}

In package.json

// {cwd}/package.json

{
  "egg": {
    "framework": "egg",
    "tsHelper": {
      "generatorConfig": {
        "model": {
          "enabled": true,
          "generator": "function",
          "interfaceHandle": "InstanceType<{{ 0 }}>"
        }
      }
    }
  }
}

or use dot-prop

// {cwd}/package.json

{
  "egg": {
    "framework": "egg",
    "tsHelper": {
      "generatorConfig.model": {
        "enabled": true,
        "generator": "function",
        "interfaceHandle": "InstanceType<{{ 0 }}>"
      }
    }
  }
}

Also you can pass options by env ( support since 1.22.0 )

  • ETS_CWD: cwd
  • ETS_FRAMEWORK: framework
  • ETS_TYPINGS: typings
  • ETS_CASE_STYLE: caseStyle
  • ETS_AUTO_REMOVE_JS: autoRemoveJs
  • ETS_THROTTLE: throttle
  • ETS_WATCH: watch
  • ETS_SILENT: silent
  • ETS_CONFIG_FILE: configFile

Custom Loader

Support since 1.24.0

egg-ts-helper support customLoader configuration of egg. see eggjs/egg#3480

Configure in config.default.ts

'use strict';

import { EggAppConfig, PowerPartial } from 'egg';

export default function(appInfo: EggAppConfig) {
  const config = {} as PowerPartial<EggAppConfig>;

  config.keys = appInfo.name + '123123';

  config.customLoader = {
    model: {
      directory: 'app/model',
      inject: 'app',
      caseStyle: 'upper',
    },
  };

  return {
    ...config as {},
    ...bizConfig,
  };
}

egg-ts-helper will auto create the d.ts for files under app/model

// This file is created by [email protected]
// Do not modify this file!!!!!!!!!

import 'egg';
type AutoInstanceType<T, U = T extends (...args: any[]) => any ? ReturnType<T> : T> = U extends { new (...args: any[]): any } ? InstanceType<U> : U;
import ExportCastle from '../../../app/model/Castle';
import ExportUser from '../../../app/model/User';

declare module 'egg' {
  interface Application {
    model: T_custom_model;
  }

  interface T_custom_model {
    Castle: AutoInstanceType<typeof ExportCastle>;
    User: AutoInstanceType<typeof ExportUser>;
  }
}

And you can easily to use it in your code.

image

Generator

If you are using loader.loadToApp or loader.loadToContext to load the instance, you should use generator config.

Example

Creating d.ts for files under app/model. You should add config generatorConfig.model in your config file.

// ./tshelper.js

module.exports = {
  generatorConfig: {
    model: {
      directory: 'app/model', // files directory.
      // pattern: '**/*.(ts|js)', // glob pattern, default is **/*.(ts|js). it doesn't need to configure normally.
      // ignore: '', // ignore glob pattern, default to empty.
      generator: 'class', // generator name, eg: class、auto、function、object
      interface: 'IModel',  // interface name
      declareTo: 'Context.model', // declare to this interface
      // watch: true, // whether need to watch files
      // caseStyle: 'upper', // caseStyle for loader
      // interfaceHandle: val => `ReturnType<typeof ${val}>`, // interfaceHandle
      // trigger: ['add', 'unlink'], // recreate d.ts when receive these events, all events: ['add', 'unlink', 'change']
    }
  }
}

The configuration can create d.ts as below.

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.

import Station from '../../../app/model/station';// <-- find all files under app/model and import then.

declare module 'egg' {
  interface Context { // <-- Context is reading from `declareTo`
    model: IModel; // <-- IModel is reading from `interface`, It will create a random interface if this field is empty
  }

  interface IModel { // <-- The same as above.
    Station: Station; // <-- Merging `Station` to IModel so we can use `ctx.model.Station` in code.
  }
}

Effect of different options

interface string

interface set to IOther.

interface IOther {
  Station: Station;
}

It will use random interface if interface is not set.

interface T100 {
  Station: Station;
}

Attentions: Must set declareTo if interface is not set.

generator string

The name of generator, available value is class function object auto.

generator: 'class'

the types created by class generator as below

interface IModel {
  Station: Station;
}

It's suitable for module wrote like this

export default class XXXController extends Controller { }

generator: 'function' ( Support since 1.16.0 )

the types created by function generator as below

interface IModel {
  Station: ReturnType<typeof Station>; // Using ReturnType to get return type of function.
}

It's suitable for module like this

export default () => {
  return {};
}

generator: 'object' ( Support since 1.16.0 )

the types created by object generator as below.

interface IModel {
  Station: typeof Station;
}

It's suitable for module like this

export default {}

generator: 'auto' ( Support since 1.19.0 )

the types created by auto generator as below. It will check types automatically.

type AutoInstanceType<T, U = T extends (...args: any[]) => any ? ReturnType<T> : T> = U extends { new (...args: any[]): any } ? InstanceType<U> : U;

interface IModel {
  Station: AutoInstanceType<typeof Station>;
}

It's suitable for every module in above.

interfaceHandle function|string

If you cannot find suitable generator in above, you can config the type by this field.

module.exports = {
  generatorConfig: {
    model: {
      ...

      interfaceHandle: val => `${val} & { [key: string]: any }`,
    }
  }
}

The generated typings.

interface IModel {
  Station: Station & { [key: string]: any };
}

The type of interfaceHandle can be string ( Support since 1.18.0 )

module.exports = {
  generatorConfig: {
    model: {
      ...

      interfaceHandle: '{{ 0 }} & { [key: string]: any }',
    }
  }
}

The generated typings are the same as above. {{ 0 }} means the first argument in function.

caseStyle function|string

caseStyle can set to loweruppercamel or function

declareTo string

Declaring interface to definition of egg. ( Support since 1.15.0 )

declareTo set to Context.model , and you can get intellisense by ctx.model.xxx

import Station from '../../../app/model/station';

declare module 'egg' {
  interface Context {
    model: IModel;
  }

  interface IModel {
    Station: Station;
  }
}

declareTo set to Application.model.subModel, and you can get intellisense by app.model.subModel.xxx

import Station from '../../../app/model/station';

declare module 'egg' {
  interface Application {
    model: {
      subModel: IModel;
    }
  }

  interface IModel {
    Station: Station;
  }
}

Defining custom generator

// ./tshelper.js

// custom generator
function myGenerator(config, baseConfig) {
  // config.dir       dir
  // config.dtsDir    d.ts dir
  // config.file      changed file
  // config.fileList  file list
  console.info(config);
  console.info(baseConfig);

  // return type can be object or array { dist: string; content: string } | Array<{ dist: string; content: string }>
  // egg-ts-helper will remove dist file when content is undefined.
  return {
    dist: 'd.ts file url',
    content: 'd.ts content'
  }
}

module.exports = {
  generatorConfig: {
    model: {
      directory: 'app/model',
      generator: myGenerator,
      trigger: ['add', 'unlink'],
    }
  }
}

or define generator to other js.

// ./my-generator.js

module.exports.defaultConfig = {
  // default watchDir config
}

// custom generator
module.exports = (config, baseConfig) => {
  // config.dir       dir
  // config.dtsDir    d.ts dir
  // config.file      changed file
  // config.fileList  file list
  console.info(config);
  console.info(baseConfig);

  // return type can be object or array { dist: string; content: string } | Array<{ dist: string; content: string }>
  // egg-ts-helper will remove dist file when content is undefined.
  return {
    dist: 'd.ts file url',
    content: 'd.ts content'
  }
}

configure in tshelper.js or package.json

// ./tshelper.js

module.exports = {
  generatorConfig: {
    model: {
      directory: 'app/model',
      generator: './my-generator',
      trigger: ['add', 'unlink'],
    }
  }
}

Demo

egg-ts-helper can works in both ts and js egg project.

TS demo: https://github.com/whxaxes/egg-boilerplate-d-ts

JS demo: https://github.com/whxaxes/egg-boilerplate-d-js

License

MIT

egg-ts-helper's People

Contributors

bung87 avatar coolyuantao avatar fengmk2 avatar hucheng91 avatar jinasonlin avatar lgtm-com[bot] avatar mansonchor avatar monkindey avatar plusmancn avatar popomore avatar semantic-release-bot avatar solais avatar viko16 avatar whxaxes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

egg-ts-helper's Issues

默认禁用自动生成 model 定义的功能,sequelize 的 @types/sequelize 定义库目前有很多问题

目前 @types/sequelize 中类型定义落后官方新版 API 非常多。其替代仓库 types/sequelize 提供了更加准确的类型定义。

目前我的项目中使用的是后者的定义,而 egg-sequelize 目前使用的是前者的定义,两者互不兼容,而 helper 默认直接扩展 Sequelize,导致现有代码类型冲突。

目前我的代码中是这样扩展 Sequelize 的

// typings/index.d.ts
// node_modules 中安装的是后者的类型定义
import { Sequelize } from 'sequelize';

declare module 'egg' {
  // 重新声明一个继承于 Sequelize 的接口,用于添加 Model
  interface MixSequelize extends Sequelize { }

  // 由于 egg-sequlize 中声明的 model 类型使用的是前者的定义,两者不兼容
  // 如果直接使用 Sequelize 类型会导致类型定义冲突
  // 所以将 app.model 的类型重定义为 MixSequelize,覆盖原定义
  export interface Application {
    model: MixSequelize;
  }

  export interface Context {
    model: MixSequelize;
  }
}
// app/model/my-model.ts
import { Model } from 'sequelize';

export class MyModel extends Model { }

export default app => {
  MyModel.init({});

  return MyModel;
}

declare module 'egg' {
  // 在此处扩展 MixSequelize 属性
  interface MixSequelize {
    MyModel: typeof MyModel;
  }
}

之前一直工作的很好,直到今天自动生成了 model.d.ts

升级 chokidar 到 3

chokidar@2 依赖 fsevents 1 版本, 在 node 14 会报错

npm WARN deprecated [email protected]: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.

执行 npx ets 时报错:SyntaxError: Cannot use import statement outside a module

打印如下内容:

❯ npx ets
[egg-ts-helper] WARN loader.loadPlugin() error: /Users/myself/Develops/mock/config/plugin.ts:1
import path from 'path';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1029:16)
    at Module._compile (internal/modules/cjs/loader.js:1078:27)
    at Module.m._compile (/Users/myself/Develops/mock/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/myself/Develops/mock/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (internal/modules/cjs/loader.js:979:32)
    at Function.Module._load (internal/modules/cjs/loader.js:819:12)
    at Module.require (internal/modules/cjs/loader.js:1003:19)
    at require (internal/modules/cjs/helpers.js:107:18)
    at loadFile (/Users/myself/Develops/mock/node_modules/egg-core/lib/utils/index.js:27:19), cwd: /Users/myself/Develops/mock, framework: egg
[egg-ts-helper] create typings/app/controller/index.d.ts (3ms)
[egg-ts-helper] create typings/app/middleware/index.d.ts (2ms)
[egg-ts-helper] create typings/config/index.d.ts (23ms)
[egg-ts-helper] create typings/app/service/index.d.ts (2ms)
[egg-ts-helper] create typings/app/index.d.ts (1ms)

我的系统环境是:

  • macOS 13.0
  • node.js 14.21.3

webstorm

我试了下这个,发现在 webstorm 中始终无法跳转到 service 下的方法上。在 vs code 里是可用的。想请教下是我姿势不对还是确实和 webstrom 的提示不兼容。

[Egg 兼容] caseStyle 参数支持函数入参

场景是这样的:
我们内部封装的插件内使用到了 Egg 的 FileLoader,其中 caseStyle 参数传入的是一个 function 用于自定义挂载的节点名。
翻阅 egg-ts-helper 的源码,发现并不支持函数传入。

不知是否有支持的考虑,可以提 PR

1.17.0 can not execute ets clean

now i am using version 1.17.1 , when i execute command "ets clean", the error "ets-clean(1) does not exist, try --help " occurred

对egg model的支持

诸如Sequelize、Mongoose等框架会使用 app/model 目录,建议开放对其他目录监听的支持

就算不做自动添加d.ts当做监听编译也好,现在egg typescript下,sequelize是完全不可用的

getEggInfo 调用 node 时使用的是直接拼接命令,当项目目录出现空格时会报错

项目路径为:/Volumes/Macintosh HD/xxxxxx

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module '/Volumes/Macintosh'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

我从1.4.2更新到1.14.0,并且使用了文件夹包含几个service一起,急需大神指教。

> egg-bin dev -r 'egg-ts-helper/register'

2018-11-22 17:46:28,246 INFO 82507 [master] node version v8.12.0
2018-11-22 17:46:28,247 INFO 82507 [master] egg version 2.11.2
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/app/controller/index.d.ts created
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/app/middleware/index.d.ts created
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/app/model/index.d.ts created
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/config/index.d.ts created
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/config/plugin.d.ts created
[egg-ts-helper] /Users/wangpeng/resp/wt-hulk/back-end/typings/app/service/index.d.ts created
2018-11-22 17:46:29,422 INFO 82507 [master] agent_worker#1:82509 started (1171ms)

/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:261
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: [egg-core] load file: /Users/wangpeng/resp/wt-hulk/back-end/app/service/TeamService.ts, error: [egg-core] load file: /Users/wangpeng/resp/wt-hulk/back-end/app/service/activityService.ts, error: ⨯ Unable to compile TypeScript:
app/service/activityService.ts(6,22): error TS2348: Value of type 'Model<any>' is not callable. Did you mean to include 'new'?

    at createTSError (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:261:12)
    at getOutput (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:367:40)
    at Object.compile (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:558:11)
    at Module.m._compile (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:439:43)
    at Module._extensions..js (module.js:664:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.loadFile (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/egg-core/lib/utils/index.js:19:19)
    at getExports (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/egg-core/lib/loader/file_loader.js:199:23)
    at ContextLoader.parse (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/egg-core/lib/loader/file_loader.js:158:25)
    at ContextLoader.load (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/egg-core/lib/loader/file_loader.js:67:24)
    at AppWorkerLoader.loadToContext (/Users/wangpeng/resp/wt-hulk/back-end/node_modules/egg-core/lib/loader/egg_loader.js:407:28)
[2018-11-22 17:46:33.457] [cfork:master:82507] worker:82516 disconnect (exitedAfterDisconnect: false, state: disconnected, isDead: false, worker.disableRefork: true)
[2018-11-22 17:46:33.457] [cfork:master:82507] don't fork, because worker:82516 will be kill soon
2018-11-22 17:46:33,457 INFO 82507 [master] app_worker#1:82516 disconnect, suicide: false, state: disconnected, current workers: ["1"]
[2018-11-22 17:46:33.458] [cfork:master:82507] worker:82516 exit (code: 1, exitedAfterDisconnect: false, state: dead, isDead: true, isExpected: false, worker.disableRefork: true)
// typings

declare module 'egg' {
  interface IModel {
    Console: {
      CrmImportRecord: ReturnType<typeof ConsoleCrmImportRecord>;
    };
    Lesschat: {
      CrmContact: ReturnType<typeof LesschatCrmContact>;
      CrmCustomer: ReturnType<typeof LesschatCrmCustomer>;
      Department: ReturnType<typeof LesschatDepartment>;
      Tag: ReturnType<typeof LesschatTag>;
      Team: ReturnType<typeof LesschatTeam>;
      User: ReturnType<typeof LesschatUser>;
    };
  }
}

在指定多个controller目录的自定义目录场景下,无法跳过中间目录

https://github.com/whxaxes/egg-ts-helper/blob/4cfed82e3ff89fed2b1ffb61dfa06d425721ce07/src/generators/class.ts#L42

比如项目以feature-base的方式建立了多个模块:

  • modules
    • session
      • controller
        • main.js
    • student
      • controller
        • main.js

期望可以生成 app.controller.session.main 和 app.controller.student.main 的声明,但由于目录结构是自定义的,实际只能生成 app.controller.session.controller.main 和 app.controller.student.controller.main

image

希望通过caseStyle的方式可以生成期望的声明

generate "\**\*" style path in windows system

https://github.com/whxaxes/egg-ts-helper/blob/8c4c770a27fc846e13f7af3e49ddfc0814f72760/src/generators/class.ts#L44

import Home from '......\app\controller\home';
if it contains sub controller,it will generate

import Home from '..\..\..\app\controller\home';
import Posts from '..\..\..\app\controller\posts';
import Sub/index from '..\..\..\app\controller\sub\index';

declare module 'egg' {
  interface IController {
    home: Home;
    posts: Posts;
    sub/index: Sub/index;
  }
}

which is a syntax error.
Can egg-ts-helper support -linux argument?

编译时不训练别tsconfig.json中的paths配置

tsconfig.json中配置如下:

{
     compilerOptions : {
          "baseUrl": ".",
          "paths": {
               "@/*": [ "app/*" ]
          },
    }
}

然后我在代码中引用模块使用的方式为:

import {ErrCode} from "@/library/common/errcode";

编译时报错:
[egg-core] load file: E:\SourceCode\QinggerSource\MicroService\ali-express-sms-service\app\controller\baseController.ts, error: Cannot find module '@/library/common/errcode'

现在可以支持生成纯js项目的扩展吗?

node version v14.19.0
egg version 2.33.1

现在看生成的d.ts文件还是空的类

import 'egg';
import ExtendResponse = require('../../../app/extend/response');
type ExtendResponseType = typeof ExtendResponse;
declare module 'egg' {
  interface Response extends ExtendResponseType { }
}

对于js文件会使用require引入

我的项目是中途换到ts的,所以项目里混合了js和ts,更新到新版本后,对于js导出的controller或service或用import xx = require(xxx)引入,但我的js代码里也统一使用了export default,导致获取引入的对象是一个{ default: [controller|service] }报错了,这个有办法配置解决吗?

Better type inference for egg-mongoose

Hi!, We're trying to use egg.js in production with mongoose, but we notice a problem about the typing for Mongoose with egg-ts-mongoose plugin.

Mongoose itself has the typing solution(separate interface declaration or use ts-mongoose), and the egg-ts-helper also generated a correct type file of model files(interface IModel), Awesome!
But when using the model in service by this.ctx.model, the model type is referred to the egg.Context.model in egg-ts-mongoose/index.d.ts(https://github.com/eggjs/egg-mongoose/blob/master/index.d.ts#L28), which type is [key: string]: mongoose.Model<any>.

So in the service, the model type is Model<any>, it's very stupid! and the solution also very easy, just override the type of context.model to IModel, by edit typing/index.d.ts as below:

import 'egg';

declare module 'egg' {
    // add below lines
    interface Context {
        model: IModel
    }
}

(Edit the typing/model/index.d.ts should has same result)

I think this job can not be done by egg-mongoose, because the interface IModel is a generated file.

I'm using WebStorm 2020.2, but I think the VSCode should has the same problem, because the context.model type refer to egg-mongoose seems a correct behavior or maybe I wrong :D

Thanks!

1.23.0 to 1.25.2, auto build diff

// This file is created by [email protected]
// Do not modify this file!!!!!!!!!

老版本不含版本号,所以不同机器与环境下这里的comment都是一致的。
新版本发现带上版本号,导致使用新老版本的开发者之间一直提示代码差异

jsconfig.json 格式错误

egg-ts-helper 自动生成的 jsconfig.json格式检测错误:
“File 'f:/myWebSpace/egg-template/node_modules/socks/typings' not found.”

"egg": "^2.15.1",
"egg-bin": "^4.11.0",
"egg-ci": "^1.11.0",
"egg-mock": "^3.21.0",
"eslint": "^5.13.0",

typings/config/index.d.ts 中 interface Service 问题

egg/index.d.ts 中声明如下:

export interface IService extends PlainObject { }
export class Service extends BaseContextClass { }

但是 egg-ts-helper 中却声明了名为 Service 的接口

https://github.com/whxaxes/egg-ts-helper/blob/8d60511ce0daa5520461c4601d52aa565344318d/src/index.ts#L126

导致以下代码无法通过类型检查

import { Service } from '@ali/my-egg';
class MyService extends Service {}

异常信息:

error TS2689: Cannot extend an interface 'Service'. Did you mean 'implements'?

js egg project中自动生成index.d.ts的问题

自动生成的代码是这样的

// This file is created by egg-ts-helper
// Do not modify this file!!!!!!!!!

import 'egg';
import ExportHome = require('../../../app/controller/home');

declare module 'egg' {
  interface IController {
    home: ExportHome;
  }
}

import ExportHome = require('../../../app/controller/home'); 这个感觉好怪啊。。 是不是应该用import ExportHome from '../../../app/controller/home';

同名interface生成解析错误

假设在service目录下有一个文件为
service/application.ts

import { Context, Service } from 'egg'

export default class ApplicationService extends Service {
  getData () {
    return 'hello world'
  }
}

自动生成的typing文件如下:
typing/app/service/index.d.ts

import 'egg'; // Make sure ts to import egg declaration at first
import Application from '../../../app/service/application';

declare module 'egg' {
  interface IService {
    application: Application;   // 这里的Application会被只想到egg下的Application,不能正确解析
  }
}

如果此时在controller中访问 ctx.service.application.getData()getData这个方法并没有真正的被解析道ctx.service.application对象上。

个人的建议能否在生成的时候添加prefix配置,使得生成的typing文件如下

typing/app/service/index.d.ts

import 'egg'; // Make sure ts to import egg declaration at first
import PrefixApplication from '../../../app/service/application';

declare module 'egg' {
  interface IService {
    application: PrefixApplication;   // 生成的prefix
  }
}

这样处理完之后就可以正确解析了。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.