You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中限制Node Express请求查询的字符串值?

解决TypeScript中Express查询参数的类型校验问题

你的核心问题是:当前代码仅通过类型断言as 'createdAt' | undefined告诉TypeScript类型,但没有做运行时校验,如果请求传入非法的sortBy值(比如updatedAt),函数会直接返回该非法值,违反了TodoQuery的类型约束。下面是几种优雅的解决思路,兼顾类型安全和运行时校验:

方案1:类型守卫+Set集合(适合多字段场景)

先定义合法的排序字段集合,再用类型守卫函数做运行时检查,让TypeScript自动收窄类型:

import { ParsedQs } from 'qs';

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

// 存储所有允许的排序字段,方便后续扩展
const ALLOWED_SORT_FIELDS = new Set<TodoSortBy>(['createdAt']);

// 类型守卫:判断值是否为合法的TodoSortBy
function isTodoSortBy(value: unknown): value is TodoSortBy {
    return typeof value === 'string' && ALLOWED_SORT_FIELDS.has(value as TodoSortBy);
}

export const extractTodoQuery = (reqQuery: ParsedQs): TodoQuery => {
    return {
        sortBy: isTodoSortBy(reqQuery.sortBy) ? reqQuery.sortBy : undefined
    };
};

方案2:枚举+枚举值校验(适合需要扩展或语义化场景)

用枚举定义合法值,通过枚举的有效值集合做校验,语义更清晰:

import { ParsedQs } from 'qs';

export enum TodoSortBy {
    CreatedAt = 'createdAt'
}

export type TodoQuery = {
    sortBy?: TodoSortBy;
};

export const extractTodoQuery = (reqQuery: ParsedQs): TodoQuery => {
    const sortByValue = reqQuery.sortBy;
    // 检查值是否在枚举的有效值范围内
    const isValid = Object.values(TodoSortBy).includes(sortByValue as TodoSortBy);
    return {
        sortBy: isValid ? (sortByValue as TodoSortBy) : undefined
    };
};

方案3:直接条件判断(适合字段少的极简场景)

如果合法字段只有一两个,直接用全等判断最简洁,TypeScript会自动识别类型:

import { ParsedQs } from 'qs';

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

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

核心逻辑说明

三种方案都做了两件事:

  1. 运行时校验:过滤掉非法的sortBy值,只保留允许的字符串或undefined
  2. 类型收窄:让TypeScript能正确识别返回值的类型,避免类型断言带来的不安全

内容的提问来源于stack exchange,提问作者OldFish5354

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:01:31