简体   繁体   中英

Restrict string value input from Node Express request query?

export type TodoQuery = {
    sortBy?: 'createdAt' | undefined;
}


export const extractTodoQuery = (reqQuery: ParsedQs): TodoQuery => {
    return {
        sortBy: reqQuery.sortBy as 'createdAt' | undefined,
    };
}

The reqQuery from extractTodoQuery function above comes from req.query in a node express app. I am trying to limit the sortBy property to certain string values or it should be undefined. Currently sortBy can still have different values in the return object based on the request query parameter. What would be an elegant way to achieve this in typescript?

You likely will want some kind of helper method to validate and return a strongly typed value. The cast doesn't force any conversion on its own and requires some validation logic.

There are many ways you could achieve this, but here is one approach by first defining an array of accepted values. Then, a helper that verifies sortBy is a string and is one of the values. If it's not a string or not one of the valid values, then it filters it out and returns undefined .

interface ParsedQs { [key: string]: undefined | string | string[] | ParsedQs | ParsedQs[] }

// Valid sorting options. Change this as you please.
// The `as const` assertion ensures only these values are valid (not any `string`).
const SORT_BY = ['createdAt', 'updatedAt', 'name'] as const;

export type TodoQuery = {
  // Infer the type based on the array so as you add/remove values the
  // types automatically update.
  sortBy?: typeof SORT_BY[number] | undefined;
}

// Helper to do the actual validation and return a strongly typed value.
const parseSortBy = (res: ParsedQs) => {
  if (typeof res.sortBy === "string") {
    return SORT_BY.find(valid => valid === res.sortBy)
  }

  return undefined;
}


export const extractTodoQuery = (reqQuery: ParsedQs): TodoQuery => {
  return {
    sortBy: parseSortBy(reqQuery),
  };
}

TypeScript playground link .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM