Create a Typescript function that has an optional object argument containing optional attributes, all of which have default values set

Looking for the most elegant Typescript solution for a function with optional parameters.

The function doSomething(num, config?) takes a number and an optional config object with a few optional parameters.

If the config type is defined as { acceptNegative?: boolean, isBig?: boolean }, then these should all be valid calls:

doSomething(num);

doSomething(num, { acceptNegative: true });

doSomething(num, { acceptNegative: true, isBig: false });

In addition, default values should be set for cases where:

  1. User doesn't provide config object => doSomething(num);
  2. User provides incomplete data in config object =>
    doSomething(num, { acceptNegative: true });

Seeking the most elegant implementation for this scenario. Any suggestions?

Answer №1

To start off, let's define a distinct type for the config parameter:

type Configuration = { enableNegative: boolean; isLarge: boolean };

Considering that you want the config parameter to be optional and allow for passing only some of its required properties, we will utilize the built-in type Partial. This will transform all properties of the provided type into optional ones:

function performTask(number: number, config: Partial<Configuration> = {}) {}

The default value for config will be {}, and in order to set default values for the properties of config, let's establish a default configuration:

const initialConfig: Configuration = {
  enableNegative: false,
  isLarge: false,
};

Within the function implementation, we'll combine initialConfig with config into a single object. It is crucial for initialConfig to precede config, otherwise it would overwrite values from config:

function performTask(number: number, config: Partial<Configuration> = {}) {
  const finalConfig = { ...initialConfig, ...config };

  console.log(finalConfig);
}

Example usage:

let number = 1;
performTask(number);
performTask(number, { enableNegative: true });
performTask(number, { enableNegative: true, isLarge: true });

playground

Answer №2

interface Settings {
 allowNegatives?: boolean;
 isLarge?: boolean;
}

function performAction(number: number, settings: Partial<Settings> = {}): void 

{ const { allowNegatives = false, isLarge = true } = settings;

// Continue with the rest of your function code

 console.log(`number: ${number}`);
 console.log(`allowNegatives: ${allowNegatives}`);
 console.log(`isLarge: ${isLarge}`);
 }

 // Examples of valid function calls
 performAction(42); // No settings object given, default values are used
 performAction(42, { allowNegatives: true }); 
 // Settings object with allowNegatives provided
 performAction(42, { allowNegatives: true, isLarge: false }); 
 // Settings object with allowNegatives and isLarge provided

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Comparing Redux and MVC models in software architecture

A new project is on the horizon, and the Product Owner has suggested using Redux for state management. However, I am hesitant to embrace this suggestion as I fail to see the advantages compared to a model-based approach. For instance, instead of utilizin ...

Difficulties setting up TypeScript in Laravel, alongside Vuejs and Inertia

Currently, my tech stack includes Laravel, Vue, and Inertia. However, I am looking to migrate everything to TypeScript, and I have encountered a roadblock that I can't seem to overcome. To aid me in this process, I referred to the following video tuto ...

Why isn't my Next.js middleware working properly with TypeScript?

My issue arises from the fact that, despite following the documentation, the middleware in Next.js is not functioning as I anticipated. I experimented with what I thought was the simplest middleware possible. I expected that when navigating to /, a conso ...

When working with Typescript and React, you may encounter an issue where an element implicitly has an 'any' type because the type 'State' has no index signature. This can lead to

In my current mini project, I am using Typescript and React. As someone new to Typescript, I am currently in the process of learning it. Within the project, I have a state defined as follows: type State = { field1: string, field2: string, field3: n ...

Unable to alter the input data within the LCJS chart

I have been utilizing LightningChart JS to create scrolling line charts. After following an official tutorial by the developers on YouTube, I was able to successfully implement the automatic generated data. Now, I am looking to modify the input to a JSON f ...

Issue arose while attempting to use Jest on a React Native application integrated with TypeScript (Jest has come across an unforeseen token)

Seems like everyone and their grandmother is facing a similar issue. I've tried everything suggested on Stack Overflow and GitHub, but nothing seems to work. It should be a simple fix considering my project is basic and new. Yet, I can't seem to ...

The Angular ResolveFn error states that the inject() function must be invoked within an injection context

As I attempted to phase out Angular's "Resolve" class implementation in favor of the "ResolveFn" functional implementation, I encountered a perplexing issue. I have a basic resolver that is preparing my data. I am facing an error that has left me puzz ...

Best practices for implementing dual ngFor directives within a single tr element?

Click here to view the page The image attached shows the view I want to iterate through two ngFor loops inside the tr tag. When using a div tag inside the tr, it's looping the button next to the tag instead of where I want it in the file table header ...

Typescript validation of tokens using Azure functions

Currently working on a website utilizing Azure Static Web App, where the login/registration is managed by Azure B2C. The backend API consists of typescript Azure functions integrated with Azure Static web app. Certain API calls can only be accessed when th ...

The process of exporting a singleton instance

I have created a new class called AppViewModel with a setting property set to 1: class AppViewModel { setting: number = 1; } export = AppViewModel; Afterward, I imported the class and instantiated it within another class named OrderEntry: import AppV ...

What is the best way to implement event handling for multi-level components/templates in Angular 5?

Currently, I am immersed in a project using Angular 5. One of the templates, called Template A, is filled with various HTML elements. I am incorporating Template A into another template, Template B, which offers additional functionalities on top of Templat ...

Updating and Preserving Content in Angular

I've encountered an issue while working on a code that allows users to edit and save a paragraph on the screen. Currently, the editing functionality is working fine and the save() operation is successful. However, after saving, the edited paragraph do ...

Configuring the tsconfig outDir will specify where the output files will be stored

What am I missing in the tsconfig settings if I only want to output files in the root directory? If I set it as "rootDir":"src" "outDir":"build", or "rootDir":"src" "outDir":"&q ...

Preventing dynamically generated components from reinitializing upon adding a new object

Within my application, there is a unique feature where components are dynamically generated through a *ngFor loop. Here is an example of how it is implemented: <div *ngFor="let actionCategory of actionCategories | keyvalue"> <h2>{ ...

"Exploring Angular 9: A guide to retrieving form data with an array of objects [Revised as of July 29th, 2020

I am encountering an issue with my Angular 9 form code. I am getting the error "ERROR TypeError: Cannot read property 'mobile_number' of undefined" and I need help in resolving this problem. <form (ngSubmit)="processForm()"> & ...

Ways to address the Generic Object Injection Sink eslint error (security/detect-object-injection)

I am seeking a solution to resolve this issue without needing to deactivate eslint. Moreover, I am eager to comprehend the cause of the error. const getMappedCard = (cardName: CardName) => { const mappedCards = { Mastercard: <Mastercard /> ...

The typings for object properties in Typescript

I recently encountered a function call in my code: var myVar = myFunction({ property: 'prop', functionProperty() { console.log(this.property); }, functionProperty2() { this.functionProperty(); } }); I' ...

Encountering "Missing requests" error while executing npm run pactTest on PACT.io

Check out the Test Repo I created: https://github.com/leongaban/pact-io-js-test https://i.sstatic.net/JESkK.jpg Anticipated Outcome To generate a Pact file for my TotalPayout.test.pact.ts script, run npm run pactTest. Findings D, [#38238] DEBUG -- : { ...

Error encountered in Storybook: The value is not iterable (property Symbol(Symbol.iterator) cannot be read)

I recently created a React library using and opted for the React + TypeScript + Storybook template. You can find the entire codebase here → https://github.com/deadcoder0904/react-typical I encountered the following error: undefined is not iterable ( ...

Utilizing express-session in TypeScript: Incorporating user information into the session

Hey, I'm currently working on implementing express-session and connect-mongodb-session in my TypeScript Express/Node API. My goal is to use express-session to create a cookie for logged-in users and automatically persist that cookie to MongoDB. Howeve ...