I used typescript to devloper koa app,I want to define my own type for ctx.state in global of app,but i don't know how to do.

Look up generics in Typescript. StateT is a generic of ParametrizedContext.
@kibertoad Thks reply!but where should I define it?
@keyiis Inside route handler definition, I would think.
@kibertoad I has many route in different file,i hope define it somewhere that can be used globally
ctx.state only relative to this request, such as verifying login token, the middleware specified ctx.state.user_name='zhangsan';
In the request method can use
let user_name= ctx.state.user_name;
@ljphilp thks reply! in my app,every route has same object in ctx.state,so i want define a interface for ctx.state at app level.
@keyiis typings are provided by https://github.com/DefinitelyTyped/DefinitelyTyped, so this repo is not a correct place to ask such questions. You should ask questions on stackoverflow.
Regarding your issue. You can pass "global" state types when you initalize Koa app:
interface MyState {
userId: number;
deptId: number;
}
const app = new Koa<{MyState}, {}>();
@kroleg thks reply!but how to define global MyState to overwrite StateT?you code only work in the files that define it,but i has many route in different file.
@ljphilp thks reply! in my app,every route has same object in ctx.state,so i want define a interface for ctx.state at app level.
// 验证token中间件
const jwt = require('jsonwebtoken');
module.exports = function (){
return function * ( next ) {
// 执行中间件的操作
let ctx = this;
if (ctx.url !== '/apis/sysmgr/user/login' && ctx.request.headers['authorization']) {
let auth_attr = ctx.request.headers['authorization'].split(' ');
if(auth_attr[0] !=='Bearer' || auth_attr.length !== 2) {
ctx.response.body = {
msg: '授权错误,请重新登陆'
};
ctx.response.status = 401;
}else{
let token = auth_attr[1];
let decoded = jwt.decode(token, process.env.JWT_SECRET);
// 如果过期了就重新登录
if (token && decoded.exp <= Date.now() / 1000) {
ctx.response.body = {
msg: '授权已经过期,请重新登陆'
};
ctx.response.status = 401;
}else{
ctx.state.user_name = decoded.user_name;
}
}
}
yield next
}
};
© 2019 GitHub, Inc.
This is my solution that registers a middleware that assigns a value to ctx.state on each request, which can be used in the current request,hope that may help you,you can also refer to my project.
@ljphilp 谢谢你的回复,我在ctx.state里保存的数据不仅用于授权,在不同的router里需要读取ctx.state里的用户信息进行数据过滤,为保证团队成员都能规范的使用ctx.state里的信息,所以我需要定义一个interface来对ctx.state里的参数类型进行约束,我首先想到的是去改koa的types,但是这对以后升级koa会造成影响,所以我想是不是能自己定义一个全局的MyStateT类型去覆盖koa的StateT,这样就不用团队成员每次要使用ctx.state时,都要去再引入一遍MyStateT,比如
apiRouter.ts这是总的路由,负责把请求转发到不同的子路由,子路由定义在各自独立的文件中
apiRouter.use('/staff', JwtAuth2Rest, staffRouter.routes());
apiRouter.use('/role', JwtAuth2Rest, RoleRouter.routes());
apiRouter.use('/cat', JwtAuth2Rest, CatRouter.routes());
......
比如staffRouter.ts
ItemRouter.post('/list', async ctx => {
let reqUser:MyStateT=ctx.state;
......
});
ItemRouter.post('/get', async ctx => {
let reqUser:MyStateT=ctx.state;
......
});
上面代码中每次使用ctx.state时都要引入我自己定义的MyStateT,这样就比较麻烦
Sorry my last message was confusing, try this, should work:
interface State {
userId: number;
}
interface Context {
something: string;
}
const app = new Koa<State, Context>().use(ctx => {
ctx.state.userId // works
ctx.something // works
});
I'm currently experimenting with TS and Koa here
Closing this as it seems to be answered. Please feel free to re-open if you still have issues with this.
Most helpful comment
Sorry my last message was confusing, try this, should work:
I'm currently experimenting with TS and Koa here