Browse Source

增加类型检查

zhusiqing 4 years ago
parent
commit
d7339dcd1c

+ 2 - 0
package.json

@@ -21,7 +21,9 @@
   },
   "devDependencies": {
     "@types/koa": "^2.11.4",
+    "@types/koa-router": "^7.4.1",
     "@types/node": "^14.11.2",
+    "@types/redis": "^2.8.27",
     "ts-node": "^9.0.0",
     "typescript": "^4.0.3"
   }

+ 17 - 17
src/app.ts

@@ -1,19 +1,20 @@
-import Koa = require('koa');
-import Router = require('@koa/router');
+// import Koa = require('koa');
+import Koa, { Context, DefaultState } from 'koa';
+import Router from 'koa-router';
 // 美化控制台
-import consola = require('consola/dist/consola');
+import consola from 'consola/dist/consola';
 // 解析post的body体
-import bodyParser = require('koa-bodyparser');
+import bodyParser from 'koa-bodyparser';
 // 部分安全相关
-import helmet = require('koa-helmet');
-import controllers = require('./controllers');
-import config = require('./config');
-import redisMiddleware = require('./middlewares/redis');
-import limitMiddleware = require('./middlewares/limit');
-import logsMiddleware = require('./middlewares/logs');
-import responseMiddleware = require('./middlewares/response');
-
-const app = new Koa();
+import helmet from 'koa-helmet';
+import controllers from './controllers';
+import config from './config';
+import redisMiddleware from './middlewares/redis';
+import limitMiddleware from './middlewares/limit';
+import logsMiddleware from './middlewares/logs';
+import responseMiddleware from './middlewares/response';
+
+const app = new Koa<DefaultState, Context>();
 // app.proxy = true;
 
 /* 中间件 */
@@ -32,16 +33,15 @@ app.use(responseMiddleware());
 
 
 
-app.on('error', (err, ctx) => {
+app.on('error', (err, ctx: Context) => {
   ctx.$response(err, 'error', false);
 });
 
 // api 路由
-const apiRouter = new Router();
+const apiRouter = new Router<DefaultState, Context>();
 apiRouter.get('/code', controllers.code);
-
 // 主路由
-const router = new Router();
+const router = new Router<DefaultState, Context>();
 router.get('/', controllers.home);
 // api路由以/api前缀
 router.use('/api', apiRouter.routes(), apiRouter.allowedMethods());

+ 1 - 1
src/config.ts

@@ -1,4 +1,4 @@
-import path = require('path');
+import path from 'path';
 const env = process.env.NODE_ENV;
 
 export = {

+ 14 - 12
src/controllers/index.ts

@@ -1,24 +1,26 @@
-import services = require('../services');
+import { Context } from 'koa';
+import services from '../services';
 
-interface Controller { home: Function, code: Function }
-const controller = {} as Controller;
-
-controller.home = async ctx => {
+export const home = async (ctx: Context) => {
   ctx.body = 'home';
 };
 
-controller.code = async ctx => {
-  const { query: { phone } } = ctx;
-  if (!phone) {
+export const code = async (ctx: Context) => {
+  interface params {
+    phone?: string
+  }
+  const params: params = {}
+  params.phone = ctx.query.phone
+  if (!params.phone) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, 'phone参数缺失', false);
     return;
   };
-  const params = {
-    phone
-  };
   const body = await services.code(ctx, params);
   ctx.body = ctx.$response(body);
 };
 
-export = controller;
+export default {
+  home,
+  code
+}

+ 7 - 6
src/middlewares/limit.ts

@@ -1,13 +1,14 @@
-import config = require('../config');
+import { Context, Next } from 'koa';
+import config from '../config';
 export = () => {
-  return async (ctx, next) => {
-    const ip = ctx.ip;
-    const key = `client_ip_limit_${ip}`;
-    const limit = Number(await ctx.$redis.get(key)) || 0;
+  return async (ctx: Context, next: Next) => {
+    const ip: string = ctx.ip;
+    const key :string = `client_ip_limit_${ip}`;
+    const limit: number = Number(await ctx.$redis.get(key)) || 0;
     if (limit > config.limit.times) {
       ctx.throw(403, '请求频次过高');
     };
-    ctx.$redis.setex(key, config.limit.time, limit + 1);
+    ctx.$redis.setex(key, config.limit.time, String(limit + 1));
     await next();
   };
 };

+ 4 - 9
src/middlewares/logs.ts

@@ -1,14 +1,9 @@
-/**
- * @description log middleware
- * @type Function
- * @param options
- */
-// import { middlewareLog } = require('../utils/logger');
-import logger = require('../utils/logger');
+import { Context, Next } from 'koa';
+import { middlewareLog } from '../utils/logger';
 
 export = () => {
-  const loggerMiddleware = logger.middlewareLog();
-  return async(ctx, next) => {
+  const loggerMiddleware = middlewareLog();
+  return async(ctx: Context, next: Next) => {
     // 静态文件不处理
     const isApi = /^\/api/.test(ctx.url);
     if (!isApi) {

+ 4 - 4
src/middlewares/redis.ts

@@ -1,7 +1,7 @@
-import redis = require('redis');
-import util = require('util');
-import consola = require('consola/dist/consola');
-import config = require('../config');
+import redis from 'redis';
+import util from 'util';
+import consola from 'consola/dist/consola';
+import config from '../config';
 
 // 创建redis连接
 const client = redis.createClient({

+ 1 - 1
src/middlewares/response.ts

@@ -1,4 +1,4 @@
-import response = require('../utils/response');
+import response from '../utils/response';
 export = () => {
   return async(ctx, next) => {
     ctx.$response = response;

+ 6 - 1
src/services/index.ts

@@ -1,4 +1,9 @@
-export const code = async (ctx, params) => {
+import { Context } from 'koa';
+export const code = async (ctx: Context, params) => {
   const code = await ctx.$redis.get(`send_sms_verify_code_sms_${params.phone}`);
   return code || 'no code';
 };
+
+export default {
+  code
+}

+ 28 - 3
src/typings/index.d.ts

@@ -1,5 +1,30 @@
-import { Consola } from "consola";
+import { Application, Context, DefaultContext } from 'koa';
+import { IMiddleware } from 'koa-router';
+import { RedisClient } from 'redis';
+import response from '../utils/response';
 
-declare module consola {
-  export var success: Function
+interface interfaceRedis {
+  get: (key: string) => Promise<string>
+  set: (key: string, value: string) => Promise<void>
+  setex: (key: string, time: number, value: string) => Promise<void>
+}
+interface logFn {
+  (message: any, ...args: any[]): void;
+}
+interface interfaceLog {
+  trace: logFn
+  debug: logFn
+  info: logFn
+  warn: logFn
+  error: logFn
+  fatal: logFn
+  mark: logFn
+}
+
+declare module 'koa' {
+  export interface Context extends DefaultContext {
+    $redis: interfaceRedis
+    $response: response
+    $log: interfaceLog
+  }
 }

+ 3 - 4
src/utils/logger.ts

@@ -1,8 +1,7 @@
-// import log4js = require('log4js');
-import log4js = require('log4js');
-import path = require('path');
+import log4js from 'log4js';
+import path from 'path';
 
-import config = require('../config');
+import config from '../config';
 
 // 输出配置
 const output = (ctx, message = '', commonInfo = {}) => {

+ 1 - 1
src/utils/observer.ts

@@ -4,7 +4,7 @@ class Observer {
     this.handle = {};
   };
   // 注册监听的事件
-  on(type = '', callback) {
+  on(type = '', callback: Function) {
     // 校验参数
     if (typeof type !== 'string') {
       const msg = `on type must is string, now is ${Object.prototype.toString.call(type)}`;

+ 7 - 3
src/utils/response.ts

@@ -1,8 +1,12 @@
-const responseHandle = (data, message = 'success', success = true) => {
+interface responseHandle {
+  (data: any, message?: string, success?: boolean): { data: any, message: string, success: boolean }
+}
+
+const responseHandle: responseHandle = (data, message = 'success', success = true) => {
   return {
     data,
-    success,
-    message
+    message,
+    success
   };
 };
 

+ 15 - 5
tsconfig.json

@@ -1,23 +1,33 @@
 {
+  "compileOnSave": true,
   "compilerOptions": {
     "outDir": "./dist",
-    "allowJs": true,
-    "target": "ES5",
+    "target": "es2017",
+    "module": "commonjs", // 采用commonjs的模块风格
     "strict": true, // 启用所有严格类型检查选项
+    "noImplicitAny": false, // 隐式any检查
+    "allowJs": true,
     "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
     "noImplicitReturns": true, // 函数末尾返回值
     "noFallthroughCasesInSwitch": true, // switch case直接break
     "allowUnreachableCode": true, // 未执行代码
     "allowUnusedLabels": true, // 未执行标签
     "strictNullChecks": true, // 空检查
-    "noImplicitAny": false, // 隐式any检查
     "checkJs": true, // 检查js错误
     "declaration": true, // 生成相应的 '.d.ts' 文件
-    "sourceMap": true, // 生成相应的 '.map' 文件
     "removeComments": true, // 删除编译后的所有的注释
     "importHelpers": true, // 从 tslib 导入辅助工具函数
     "moduleResolution": "node", // 选择模块解析策略
-    "module": "commonjs" // 采用commonjs的模块风格
+    "experimentalDecorators": true,
+    "emitDecoratorMetadata": true,
+    "charset": "utf8",
+    "pretty": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "inlineSourceMap": true,
+    "skipLibCheck": true,
+    "skipDefaultLibCheck": true,
+    "esModuleInterop": true
   },
   "include": [
     "./src"

+ 14 - 0
yarn.lock

@@ -201,6 +201,13 @@
   dependencies:
     "@types/koa" "*"
 
+"@types/koa-router@^7.4.1":
+  version "7.4.1"
+  resolved "https://registry.yarnpkg.com/@types/koa-router/-/koa-router-7.4.1.tgz#3702a4cabe4558cc4eec70d5574acc04beecff7c"
+  integrity sha512-Hg78TXz78QYfEgdq3nTeRmQFEwJKZljsXb/DhtexmyrpRDRnl59oMglh9uPj3/WgKor0woANrYTnxA8gaWGK2A==
+  dependencies:
+    "@types/koa" "*"
+
 "@types/koa@*", "@types/koa@^2.11.4":
   version "2.11.4"
   resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.11.4.tgz#8af02a069a9f8e08fa47b8da28d982e652f69cfb"
@@ -235,6 +242,13 @@
   resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
   integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
 
+"@types/redis@^2.8.27":
+  version "2.8.27"
+  resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.27.tgz#9bc89b472f3fc4a57a06c1823f2fc860c6c2fdf3"
+  integrity sha512-RRHarqPp3mgqHz+qzLVuQCJAIVaB3JBaczoj24QVVYu08wiCmB8vbOeNeK9lIH+pyT7+R/bbEPghAZZuhbZm0g==
+  dependencies:
+    "@types/node" "*"
+
 "@types/serve-static@*":
   version "1.13.5"
   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53"