[eggjs/egg][RFC] d.ts中增加model的提示

2024-08-05 417 views
9
背景

const model = { user_id: { type: INTEGER(11), primaryKey: true, autoIncrement: true, }, name: STRING(30), // 名字 createdAt: DATE, updatedAt: DATE, deletedAt: DATE, }

const User = app.model.define('user', model, { paranoid: true, freezeTableName: true, underscored: false, }) User.associate = function() { } User.model = model return User }

这时候 ReturnType<typeof ExportUser>的类型就是any,于是

![image](https://user-images.githubusercontent.com/26317926/61524130-5dd33200-aa48-11e9-9dc0-8d288564c1dd.png)

## 思路

> 目前有两种思路
1. 在每个model文件里添加注释
```js
'use strict'
/**
 * @param {Egg.Application} app
 */
module.exports = app => {
  const {
    INTEGER,
    DATE,
    STRING,
  } = app.Sequelize

  const model = {
    user_id: {
      type: INTEGER(11),
      primaryKey: true,
      autoIncrement: true,
    },
    name: STRING(30), // 名字
    createdAt: DATE,
    updatedAt: DATE,
    deletedAt: DATE,
  }

  const User = app.model.define('user', model, {
    paranoid: true,
    freezeTableName: true,
    underscored: false,
  })
  User.associate = function() {
  }
  User.model = model
  return User
}
  1. d.ts里增加一个可以自定义的CusModel
    //egg-sequelize
    //index.d.ts
    declare module 'egg' {
    interface CusModel extends  sequelize.ModelCtor<any>
    }

    然后在egg-ts-helper生成的model添加

    declare module 'egg' {
    interface CusModel {}
    interface IModel {
    User: (any extends ReturnType<typeof ExportUser>
      ? CusModel
      : ReturnType<typeof ExportUser>) &
      CusModel
    }
    }

第一种不需要修改插件和egg-ts-helper,第二种类型提示可以由插件控制,同时保留了model里面返回的类型

跟进
  • [ ] some task
  • [ ] PR URL

回答

5

目前本来就是可以通过注释的方式,结合 egg-ts-helper 实现智能提示( https://github.com/whxaxes/blog/issues/16

第一种肯定依赖 egg-ts-helper,不然你的注释用 Egg.Application 里哪来的 Egg 类型,除非你自己手动写。 看错,修改看成依赖了,以为说不需要依赖

3

ReturnType 为 any 是因为你的 app 是 any .... 所以才需要注释

3

总的来说,目前 sequelize model 应该是已经支持智能提示了,在 ts 及 js 项目中应该都支持,如果无提示那就是 bug

6

啊没看文档,原来第一种已经有了,感谢,如果能把注释加在[examples-sequelize] (https://github.com/eggjs/examples/blob/master/sequelize/app/model/post.js)就更好了

第二点,目前 egg-sequelize 已经加了 IModel 的声明:https://github.com/eggjs/egg-sequelize/blob/master/index.d.ts#L32

IModel这个是加在app.model和ctx.model上了

interface Application {
    Sequelize: typeof sequelize;
    model: IModel;
  }

  // extend context
  interface Context {
    model: IModel;
  }

然后User挂在IModel下

declare module 'egg' {
  interface IModel {
    User: ReturnType<typeof ExportUser>;
  }
}

这样的话没有注释的话,this.ctx.model.User 还是无法使用sequelize相关的方法

5

@supperchong 没有注释的话,你是怎么都没法用的,因为你的 app 是 any ,编辑器没法分析出你 app.model.define 返回的是什么类型。

4

@whxaxes 但是第二种方法的话,虽然编辑器没法分析app.model.define 返回的是什么类型,但是egg-sequelize的插件可以提供,不过需要egg-ts-helper配合

9

@supperchong 我没懂你的意思,你是指不用写注释就能获得智能提示?写个例子看看?

9

@supperchong 哦,你是指外面使用的时候能拿到智能提示么。。。。那现在不是已经支持了?

2

@supperchong 你的意思是,让 egg-ts-helper 支持针对 egg-sequelize 生成下面这种声明?

(any extends ReturnType<typeof ExportUser>
      ? CusModel
      : ReturnType<typeof ExportUser>) &
      CusModel

如果是这样,目前也是支持的,就需要自定义一下 egg-ts-helper 的配置( https://github.com/whxaxes/egg-ts-helper/blob/master/README.zh-CN.md#interfacehandle-functionstring ),可以指定生成的声明是什么样的结构。


不过。。。写个 jsdoc 注释就能一劳永逸的前提下,走这种定制的配置感觉有点舍近求远了。

1

对就是这样,感谢

6

还是建议写个 jsdoc 吧,最低成本了

5

这个问题已解决,我关掉先,有需要再开