iuv-egg-ts-helper
v1.0.1
Published
egg typescript helper for iuv
Downloads
3
Readme
iuv-egg-ts-helper
修改说明
修改自 egg-ts-helper
,适配iuv同构框架。
以下为原README
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
or
yarn add egg-ts-helper --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 watchDirs, your can ignore multiple dirs with comma like: -i controller,service
-e, --enabled [dirs] Enable watchDirs, 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 |
| configFile | string
| {cwd}/tshelper.(js|json) | configure file path |
| watchDirs | object
| | generator configuration |
You can configure the options above in ./tshelper.js
./tshelper.json
or package.json
.
In tshelper.js
// {cwd}/tshelper.js
module.exports = {
watchDirs: {
model: {
enabled: true,
generator: "function",
interfaceHandle: "InstanceType<{{ 0 }}>"
},
}
}
In tshelper.json
// {cwd}/tshelper.json
{
"watchDirs": {
"model": {
"enabled": true,
"generator": "function",
"interfaceHandle": "InstanceType<{{ 0 }}>"
},
}
}
In package.json
// {cwd}/package.json
{
"egg": {
"framework": "egg",
"tsHelper": {
"watchDirs": {
"model": {
"enabled": true,
"generator": "function",
"interfaceHandle": "InstanceType<{{ 0 }}>"
}
}
}
}
}
or use dot-prop
// {cwd}/package.json
{
"egg": {
"framework": "egg",
"tsHelper": {
"watchDirs.model": {
"enabled": true,
"generator": "function",
"interfaceHandle": "InstanceType<{{ 0 }}>"
}
}
}
}
Also you can pass options by env ( support since 1.22.0 )
ETS_CWD
: cwdETS_FRAMEWORK
: frameworkETS_TYPINGS
: typingsETS_CASE_STYLE
: caseStyleETS_AUTO_REMOVE_JS
: autoRemoveJsETS_THROTTLE
: throttleETS_WATCH
: watchETS_SILENT
: silentETS_CONFIG_FILE
: configFile
Custom Loader
Support since 1.24.0
egg-ts-helper
support customLoader configuration of egg. see https://github.com/eggjs/egg/issues/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.
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 watchDirs.model
in your config file.
// ./tshelper.js
module.exports = {
watchDirs: {
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 usinggenerator: '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 = {
watchDirs: {
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 = {
watchDirs: {
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 lower
、upper
、camel
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 = {
watchDirs: {
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 = {
watchDirs: {
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