Ben Botvinick
Ben Botvinick

Reputation: 3345

TypeScript require both parameters or neither

Is there any way to define a function that requires either both conditional parameters be provided, or neither? For example:

function greet(firstName?: string, lastName?: string) {
  if (fistName && lastName) console.log(`Hello, ${firstName} ${lastName}!`)
  else console.log('Hello, World!')
}

greet('John', 'Doe') // Hello, John Doe!
greet() // Hello, World!
greet('John') // Invalid

I realize I could just use object destructuring, create two methods, or add more if statements, but I'm curious to see if this is possible. Thanks!

Upvotes: 2

Views: 384

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371168

You can use overloading for the function's type:

type Greet = {
     (firstName: string, lastName: string): void;
     (): void;
};
const greet: Greet = (firstName?: string, lastName?: string) => {
  if (firstName && lastName) console.log(`Hello, ${firstName} ${lastName}!`)
  else console.log('Hello, World!')
};

greet('John', 'Doe'); // Hello, John Doe!
greet(); // Hello, World!
greet('John'); // Invalid

Playground link

Still, it's a bit repetitive and somewhat ugly. While doable, I'd prefer using separate functions when possible.

A similar approach, using an object instead of separate parameters:

type GreetParam = {
     firstName: string;
     lastName: string;
};
const greet = (param?: GreetParam) => {
  if (param) console.log(`Hello, ${param.firstName} ${param.lastName}!`)
  else console.log('Hello, World!')
};

greet({ firstName: 'John', lastName: 'Doe' }); // Hello, John Doe!
greet(); // Hello, World!
greet({ firstName: 'John' }); // Invalid
greet({}); // Invalid

Upvotes: 3

Related Questions