一键导入
avoid-repeated-params
Use when functions have multiple parameters of same type. Use when parameter order is easy to confuse. Use when designing function signatures.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when functions have multiple parameters of same type. Use when parameter order is easy to confuse. Use when designing function signatures.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when defining global types. Use when augmenting window. Use when typing environment variables. Use when working with build-time constants. Use when configuring type definitions.
Use when migrating JavaScript to TypeScript. Use when gradually adopting TypeScript. Use when working with mixed codebases. Use when converting large projects. Use when teams are learning TypeScript.
Use when writing asynchronous code. Use when tempted to use callbacks. Use when composing multiple async operations.
Use when creating types from example data. Use when types don't match all cases. Use when API responses vary.
Use when writing type annotations on variables. Use when TypeScript can infer the type. Use when code feels cluttered with types.
Use when defining array-like types. Use when tempted to use number as index type. Use when understanding array keys.
| name | avoid-repeated-params |
| description | Use when functions have multiple parameters of same type. Use when parameter order is easy to confuse. Use when designing function signatures. |
Multiple parameters of the same type invite mix-ups.
When a function takes (string, string, string), it's easy to pass arguments in the wrong order. Use named parameters (objects) to make calls self-documenting.
If parameter order is confusing, use an object.
Names prevent mix-ups better than positions.
Remember:
function sendEmail(
to: string,
subject: string,
body: string
) { /* ... */ }
// Which is which?
sendEmail(
'Hello!',
'bob@example.com',
'Welcome to our service'
);
// Whoops! Subject and recipient are swapped
TypeScript sees (string, string, string) - all valid, no error.
function sendEmail(params: {
to: string;
subject: string;
body: string;
}) { /* ... */ }
// Now it's clear:
sendEmail({
to: 'bob@example.com',
subject: 'Hello!',
body: 'Welcome to our service'
});
// Wrong order is obvious:
sendEmail({
to: 'Hello!', // Clearly wrong
subject: 'bob@example.com', // Obviously an email
body: 'Welcome'
});
// Clear: types are different
function setProperty(obj: object, key: string, value: unknown) { }
// Clear: number vs string
function pad(str: string, length: number) { }
// Nothing to confuse
function greet(name: string) { }
// Math functions are universally position-based
function max(a: number, b: number) { }
// Array methods follow established patterns
function slice(arr: any[], start: number, end: number) { }
// Clean function signature and implementation
function sendEmail({
to,
subject,
body
}: {
to: string;
subject: string;
body: string;
}) {
console.log(`Sending to ${to}: ${subject}`);
// Use to, subject, body directly
}
interface SendEmailOptions {
to: string;
subject: string;
body: string;
cc?: string[];
priority?: 'high' | 'normal' | 'low';
}
function sendEmail({
to,
subject,
body,
cc = [],
priority = 'normal'
}: SendEmailOptions) {
// ...
}
// Call with just required params
sendEmail({ to: 'bob@example.com', subject: 'Hi', body: 'Hello!' });
// Or with optional params
sendEmail({
to: 'bob@example.com',
subject: 'Urgent',
body: 'Please respond',
priority: 'high'
});
// Required first parameter, options object second
function createElement(
tagName: string,
options?: {
className?: string;
id?: string;
children?: Element[];
}
) { /* ... */ }
createElement('div');
createElement('div', { className: 'container', id: 'main' });
// Bad: which is format, which is locale?
function formatDate(date: Date, format: string, locale: string): string { }
formatDate(new Date(), 'en-US', 'YYYY-MM-DD'); // Wrong order!
// Good: named parameters
function formatDate(
date: Date,
options: { format: string; locale: string }
): string { }
formatDate(new Date(), { format: 'YYYY-MM-DD', locale: 'en-US' });
// Bad: easy to confuse width/height, x/y
function drawRect(x: number, y: number, width: number, height: number) { }
// Better: grouped semantically
function drawRect(
position: { x: number; y: number },
size: { width: number; height: number }
) { }
// Best: named everything
interface DrawRectOptions {
x: number;
y: number;
width: number;
height: number;
}
function drawRect(options: DrawRectOptions) { }
Pressure: "Object syntax is longer"
Response: One-time verbosity prevents ongoing confusion.
Action: Use named parameters for clarity; brevity isn't worth bugs.
Pressure: "Other libraries use positional params"
Response: You're not other libraries. Make your API clear.
Action: Design for your users, not convention.
| Excuse | Reality |
|---|---|
| "It's only two parameters" | Two strings are still confusable |
| "IDE shows parameter names" | Names shown, not enforced |
| "We have good documentation" | People don't read docs |
// DON'T: Same-type positional parameters
function fn(a: string, b: string, c: string) { }
fn('x', 'y', 'z'); // What's what?
// DO: Named parameters
function fn(params: { a: string; b: string; c: string }) { }
fn({ a: 'x', b: 'y', c: 'z' }); // Clear!
// OK: Different types
function fn(name: string, count: number) { }
// OK: Single parameter
function fn(message: string) { }
Named parameters prevent argument mix-ups.
When functions take multiple parameters of the same type, use an object parameter. The small verbosity cost is repaid many times over in prevented bugs and improved readability.
Based on "Effective TypeScript" by Dan Vanderkam, Item 38: Avoid Repeated Parameters of the Same Type.