簡體   English   中英

打字稿,檢查請求正文是否為用戶類型,否則拋出錯誤

[英]Typescript, check if request body has type User otherwise throw error

我被困在試圖解決一個問題。 我正在使用 express js 來構建一個 rest api。 我希望用戶能夠更新他們的個人資料。

我創建了一個用戶模型:

export type User = {
    email: string
    creation_date: number
    first_name?: string
    last_name?: string
    payment_detals?: {
        iban: string
        last_updated: string
    }
    address?: {
        city: string
        street: string
        house_number: string
        postal_code: string
    }
    products?: string[]
}

但我想接收請求正文並更新數據庫中該用戶的值(無 SQL、Firebase)。 但我不希望用戶添加用戶類型中未指定的字段。

如何檢查請求正文是否具有 User 類型,如果沒有拋出錯誤?

路線:

const edit = async (req: Request, res: Response) => {
    try {
        let data = req.body
        if (data instanceof User)
    } catch (err) {
        return res.status(501).json({ error: err.message })
    }
    return res.status(200).json({ status: 'ok' })

我在互聯網上找不到任何幫助,所以也許有人可以幫助我?

例如,如果 post 請求的有效負載是:

{
  "name": "Jack"
}

它應該拋出一個錯誤,因為name不是 User 的成員。

我該如何解決這個問題? 感謝所有幫助!


更新現在嘗試類:

export class CUser {
    email: string
    creation_date: number
    first_name?: string
    last_name?: string
    payment_detals?: {
        iban: string
        last_updated: string
    }
    address?: {
        city: string
        street: string
        house_number: string
        postal_code: string
    }
    products?: string[]
}

路線

const edit = async (req: Request, res: Response) => {
    let data = req.body
    console.log(data instanceof CUser)
    return res.status(200).json({ status: 'ok' })
}

當 request.body 是:

{
    "email": "mike@gmail.com",
    "creation_date": 849349388935
}

data instanceof CUserdata instanceof CUser將始終為 false。 等等是不是因為數據是一個對象?..

您在 Typescript 中定義的類型或接口在轉換為 Javascript 時會被剝離,因此您將無法在運行時檢查類型。

您需要做的是創建一個類型保護函數,無論您的請求是否具有這些特定的User屬性,該函數都會斷言 true 或 false。

有關一個很好的示例,請參閱: 如何在 TypeScript 中檢查運行時的對象類型?

您可以在 typescript class 中創建一個構造函數或函數,它將獲取 req.body 並僅從對象中選擇所需的鍵,分配給此成員變量並返回 User 對象的新實例。

現在您可以對 User 實例應用檢查,也可以在 User 類中創建一個 validateObject 方法

我通過編寫一個函數來解決這個問題,該函數將請求正文與我期望的類型進行比較,並且效果很好! 如果字段有問題或必填項有誤,服務器會立即拋出錯誤。 下面是一些代碼片段:

功能

export type Schema = {
    fields: { [key: string]: string }
    required?: string[]
}

const required = (obj: any, required: string[]) => {
    for (let key of required) {
        if (obj[key] === undefined) return false
    }
    return true
}

export const validate = async (obj: any, model: Schema) => {
    if (model.required) {
        const status = required(obj, model.required)
        if (!status) return false
    }

    for (let key of Object.keys(obj)) {
        if (model.fields[key] === undefined) return false
        else if (typeof obj[key] !== model.fields[key]) return false
    }
    return true
}

示例類型

import { Schema } from './'

export type User = {
    email: string
    creation_date: number
    subscription: string
    first_name?: string
    last_name?: string
    payment_detals?: {
        iban: string
        last_updated: string
    }
    address?: {
        city: string
        street: string
        house_number: string
        postal_code: string
    }
    categories?: string[]
    products?: {
        ean: number
        category?: string
        notes?: string
    }[]
}

export const UserSchema: Schema = {
    fields: {
        email: 'string',
        subscription: 'string',
        first_name: 'string',
        last_name: 'string',
        payment_details: 'object',
        address: 'object',
        categories: 'object',
        products: 'object',
    },
    required: ['email']
}

在服務器上

let status = await validate(body, UserSchema)
if (!status) return res.status(422).json(Message.error.wrong_request_body)

// else continue

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM