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

如何在特定场景下将TypeScript可选属性设为必填?

如何将TypeScript类型的可选属性在特定场景设为必填?

假设我们有一个表示API响应的TypeScript类型,其中部分属性是可选的:

type Response = {
  id: string;
  users?: User[];
  // ... 其他可选属性
};

当调用API时传入特定参数,能确定users字段一定会返回,此时希望将该属性设为必填,避免代码中出现data.users可能为undefined的情况(比如使用react-query时)。

最优解决方案:自定义工具类型指定必填属性

TypeScript内置的Required工具类型会将所有可选属性转为必填,无法针对单个属性。我们可以结合Omit和Pick实现一个仅将指定属性设为必填的工具类型:

// 自定义工具类型:将T类型中指定的K属性设为必填
type RequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

使用时直接声明需要转为必填的属性即可,users的类型会沿用原Response中的定义,无需手动指定:

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

const { data } = useQuery(
  ['businesses'],
  async (): Promise<RequiredKeys<Response, 'users'>> => {
    const { data } = await axios.get(url, {
      params: queryParams, // 该参数确保users字段必返回
    });
    return data;
  }
);

// 此时data.users的类型为User[],不再是可选的

其他可选方案

改进泛型方案

如果你愿意修改原Response类型,可以用泛型控制指定属性是否必填,避免调用方手动指定属性类型:

// 泛型T标记users是否必填,默认非必填
type Response<T extends boolean = false> = {
  id: string;
  users: T extends true ? User[] : User[] | undefined;
  // ... 其他属性
};

使用时通过布尔值控制:

  • 需要users必填:Promise<Response<true>>
  • 默认非必填:Promise<Response>

不推荐的原泛型方案

你之前尝试的泛型方案需要调用方指定users的类型,不仅不够直观,还会导致原类型中users的定义变化时,所有调用处都需要同步修改,维护成本较高,因此不推荐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:10:19