javascript - Express.js - 在请求对象中通过主体转换接口(interface)

标签 javascript node.js typescript express

我编写了与 ASP.NET MVC 结构类似的基础,并在我的 github ( express-mvc) 上发布。一切正常,但我无法在 request 对象中转换 body 以适应任何界面。

这正是我想要的:

export default interface Post {
    title: string
    body: string
}
import Post from '@models/user'

router.post("/post", (req: Request, res: Response) => {
    const Model: Post = req.body
})

但在运行时没有接口(interface),因为在 JavaScript 上没有接口(interface)。当我使用它时,将以 JavaScript 输出

const Model;
Model = req.body

那样的话,它会将接口(interface)的非成员属性赋值给我的变量。

简而言之,我需要Model 变量中接口(interface)的已知属性。

我在这个项目中暂时使用解构来解决问题

import Post from '@models/user'

router.post("/post", (req: Request, res: Response) => {
    const { title, body }: Post = req.body

    const Model: Post = <Post>{
        title,
        body
    };
})

你有什么建议


用类解决问题

function castByBody<Model>(source: {}, modelProperties: any[]): Partial<Model> {
    const post: Partial<Model> = {};
    for (const key of modelProperties) {
        post[key] = source[key];
    }
    return post;
}

class User {
  public first_name: string = null
  public username: string = null
  public email: string = null
  public password: string = null
  public age: number = null
}

let user = new User() // create new instance
let userProperties: any[] = Object.getOwnPropertyNames(user) // get all properties from instance

const reqBody = { 
  first_name: "afulsamet",
  username: "aful",
  email: "afulsamet@gmail.com",
  password: "333222233",
  title: "member", 
  age: 18 
} // user instance does not have title property

const model: Partial<User> = castByBody<User>(reqBody, userProperties);

console.log(model)

输出和控制台一样

{
  age: 18
  email: "afulsamet@gmail.com"
  first_name: "afulsamet"
  password: "333222233"
  username: "aful"
}

TypeScript playground

最佳答案

When it's that way, it assignment non-members property of interface to my variable.

如果您不想那样,则不能使用强制转换(这不是真正的强制转换,在 TypeScript 中称为类型断言)。您必须创建一个新对象。

你可以像现在这样用解构来做到这一点,尽管你可以通过更快地(在参数列表中)让它感觉不那么笨重,而且你不需要对其进行类型断言,TypeScript 会看到您分配的内容是可以接受的:

router.post("/post", ({body: { title, body }}, res: Response) => {
    const Model: Post = {
        title,
        body
    };
})

根据类型信息自动执行此操作(无需键入 titlebody)需要 TypeScript 提供运行时类型信息,即 currently outside TypeScript's goals (尽管这是一项普遍要求的功能)。

当然,它不一定是解构的。你可以有一个属性名称数组(TypeScript 不会给你的东西),可能在类型旁边定义,然后使用它:

const PostKeys = ["title", "body"];

然后

router.post("/post", ({body}, res: Response) => {
    const Model: {} as Post;
    for (const key of PostKeys) {
        Model[key] = body[key];
    }
})

也许甚至让它成为一个可重用的函数

function createPost(source: any): Post {
    const post: {} as Post;
    for (const key of PostKeys) {
        post[key] = source[key];
    }
    return post;
}

然后

router.post("/post", ({body}, res: Response) => {
    const Model: createPost(body);
})

关于javascript - Express.js - 在请求对象中通过主体转换接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56481858/

相关文章:

javascript - 如何div淡出

javascript - 视差滚动 : Unwanted gap in between layers

javascript - 如何通过在Javascript对象中创建新属性来为不存在的属性设置值?

typescript - 如何实现通用的 First "case/switch"类型

javascript - angularjs ns-显示逻辑流程

javascript - 蒙戈 GeoJSON : location object expected

node.js - 如果不活动,如何使 gulp-watch 超时

node.js - Reactjs 要求变量中的图像 url 不起作用

json - 在 Node Typescript 中导入 JSON 文件

angular - ngx-translate 即时函数不是抛出 : Unit testing 的函数