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

TypeScript如何让类型含必填字段但函数参数对应字段可选?

DRY Solution for Required Type with Optional Function Parameter in TypeScript

Great question! This is a perfect use case for TypeScript's utility types to keep your code DRY while maintaining the required type constraints. Here's a clean solution that avoids duplicating type definitions:

Step 1: Define the Core Required Type

First, we'll define the Notification type with all its required fields, including the mandatory category:

type Notification = {
  title: string;
  message: string;
  category: 'good' | 'bad';
};

Step 2: Create a Reusable Function Parameter Type

We'll use TypeScript's Omit utility type to remove the mandatory constraint from category, then re-add it as an optional field—reusing the category type from our core Notification to avoid duplication:

type NotifyParams = Omit<Notification, 'category'> & {
  category?: Notification['category'];
};

Step 3: Implement the notify Function

Now we can build the notify function, setting 'good' as the default value for category. We'll merge the input params with the default to ensure we always end up with a valid Notification object:

function notify(params: NotifyParams): Notification {
  const fullNotification: Notification = {
    category: 'good',
    ...params,
  };

  // Add your notification logic here (e.g., display to user, log)
  console.log('Displaying notification:', fullNotification);
  
  return fullNotification;
}

Usage Examples

You can now call notify with or without the category parameter, and TypeScript will enforce type safety everywhere:

// Works: category defaults to 'good'
notify({ title: 'Success!', message: 'Your task was completed.' });

// Works: explicitly set category to 'bad'
notify({ title: 'Error', message: 'Something went wrong.', category: 'bad' });

// Throws TypeScript error: missing required 'title' field
notify({ message: 'Oops!' });

// Throws TypeScript error: invalid category value
notify({ title: 'Warning', message: 'Heads up', category: 'neutral' });

Why This Works

  • DRY Compliance: All type definitions stem from the core Notification type. If you ever need to update the allowed category values (e.g., add 'neutral'), you only need to modify the Notification type once—no duplicate changes needed.
  • Type Safety: The Notification type enforces that any final notification object has all required fields, while the NotifyParams type makes category optional for function calls.
  • Clarity: Separating the core type from the function parameter type makes your intent clear: Notification represents a complete, valid notification, while NotifyParams represents the input options for creating one.

Even More Concise Version (If You Don't Need Reusable Params)

If you don't need to reuse the NotifyParams type elsewhere, you can inline it directly in the function definition for brevity:

function notify(
  params: Omit<Notification, 'category'> & { category?: Notification['category'] }
): Notification {
  return { category: 'good', ...params } as Notification;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:55:15