Make TypeScript parameter optional if it is not supplied

I am working with an interface that defines scenes and their parameters:

export interface IScene<R extends string> {
  path: R;
  params?: SceneParams;
}

The SceneParams interface looks like this:

export interface SceneParams {
  [key: string]: string;
}

Creating scene types works well, for example:

interface PostDetailScene extends IScene<PostRoute.Detail> {
  params: PostDetailSceneParams;
}

In the above code snippet, PostDetailSceneParams can be defined as:

export interface PostDetailSceneParams extends SceneParams {
  postId: string;
}

All type checks are correct in the following examples:

// CORRECT
getPathWithParams({
  path: PostRoute.Detail,
  params: { postId: '4' },
});

getPathWithParams({
  path: UserRoute.List,
});

getPathWithParams({
  path: UserRoute.List,
  params: undefined,
});

// ERROR
getPathWithParams({
  path: PostRoute.Detail,
  params: undefined,
});

getPathWithParams({
  path: PostRoute.Detail,
});

getPathWithParams({
  path: UserRoute.List,
  params: { wrongParam: 'value' },
});

Now, when dealing with a scene where no props need to be passed, such as UserListScene:

interface UserListScene extends IScene<UserRoute.List> {
  params?: never;
}

The question arises whether there is a way to alter the IScene interface so that explicitly typing params?: never or params?: undefined when no parameters are needed can be avoided. Ideally, it would look like this:

interface UserListScene extends IScene<UserRoute.List> {}

or:

type UserListScene = IScene<UserRoute.List>;

EDIT:

The function for retrieving paths with parameters should also undergo proper type checking:

export function getPathWithParams(scene: Scene): string {
  if (!scene.params) {
    return scene.path;
  }

  let pathWithParams: string = scene.path;
  const paramsAsString = Object.keys(scene.params);

  paramsAsString.forEach((param: string) => {
    pathWithParams = pathWithParams.replace(`:${param}`, scene.params[param]);
  });

  return pathWithParams;
}

Answer №1

To tackle this problem, you can utilize two distinct interfaces (since that is essentially what we are dealing with):

export interface IPage<T extends string> {
  url: T;
}

export interface IPageWithParams<T extends string> {
  url: T;
  parameters: PageParameters;
}

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

The issue at hand in Ionic 2 / Angular 2 is that the NPM module is being utilized as a value instead of referring to a type

I'm currently working on integrating the npm module "ajv" into my Ionic 2 (Angular 2) project. You can find more information about this module at . After running "npm install ajv --save", I proceeded to make some modifications to my app.modules.js fi ...

Generate steps using Material UI/React Stepper to create organized pages (similar to Table Pagination)

As I venture into using Material UI along with React, my goal is to create organized "pages" consisting of steps in sets of four for a specific process. My initial attempt displayed all 10 steps on a single view, despite having the pagination correctly ca ...

Changing the names of the remaining variables while object destructuring in TypeScript

UPDATE: I have created an issue regarding this topic on github: https://github.com/Microsoft/TypeScript/issues/21265 It appears that the syntax { ...other: xother } is not valid in JavaScript or TypeScript, and should not compile. Initial Query: C ...

"Implementing Ionic 2 tabs allows for retrieving the previously selected option with the

Here is the code I am currently working on: onTabsChange(abc) { let selected_tab = this.tabs.getSelected(); let tab_index = selected_tab.index; console.log(tab_index); // should print current tab index but it prints previously selected tab index ...

JavaScript anchor scrolling

I am currently working on building a website with anchor navigation similar to what is used on platforms like Facebook and Google Mail. I have managed to get it partially working, but there are still some issues. For example, when I load the page with some ...

The customer opts to store all images indefinitely into the data stream

I have set up a node server that captures images from a webcam at regular intervals and sends them to the client using the Delivery.js node module. Upon monitoring the browser resources in Chrome development tools, it appears that each image sent is being ...

Exploring the bewilderment of retrieving values in a JavaScript

I'm confused about the return value of this code snippet: function foo() var ret = 0; var xhr=send_request( "bla", function() { // perform actions based on AJAX response // set the value of ret based on the response } ); return re ...

Can you explain the purpose of useEffect in React?

As a beginner in learning React, I have been able to grasp the concept of the useState hook quite well. However, I am facing some difficulties understanding the useEffect hook. I have tried looking through the documentation, searching online, and even wat ...

There seems to be an issue with accessing the Angular module, even though it has been clearly

While attempting to execute the code below, two errors are encountered: Error: [$injector:nomod] Module 'rooms' is not available! The module name is spelled correctly and loaded dependencies have been included. The modules are structured in the c ...

NodeJS: Error - Unexpected field encountered in Multer

Having trouble saving an image in a SQL database and getting the error message MulterError: Unexpected field. It worked fine in similar cases before, so I'm not sure what's wrong. H E L P!! <label id="divisionIdLabel" for="divis ...

Is there a way to construct a Javascript function, without relying on JQuery, for fetching JSON objects from varying

I have been searching for a non-JQuery AJAX function that can fetch data from a URL and return it as a JSON object. For example, let's say I want to display information about Users from one JSON located at URL1 and also include information about Post ...

Currently, I am creating a regular expression to manage a specific task, but I have hit a roadblock in

Criteria: The string must not contain any uppercase letters. Special characters such as '^$.?*+()' are not allowed in the string. If the string includes '[', it must be followed by zero or more characters other than '[' and & ...

How can the horizontal scroll bar width be adjusted? Is it possible to create a custom

Within my div, I have implemented multiple cards that scroll horizontally using the CSS property: overflow-x: scroll; This setup results in a horizontal scrollbar appearing under the div, which serves its purpose. However, I would prefer a customized scr ...

Creating a Login Form with Node.js and MongoDB

Currently, I am working on a node.js application that is connected to a remote mongoDB server. Inside the database are specific custom codes that have been created and shared with selected users. The main objective is to restrict access to the rest of the ...

Add HTML content to a specific div according to the option selected in a drop-down menu

I am currently working on a project where I need a button to insert HTML content into a div based on the value selected in a select box. However, the functionality is not working as intended. Upon clicking the button, nothing happens. I am unsure of what t ...

Perform an additional HTTP request and utilize the response within the existing Observable

In my Angular 2 project, I am utilizing the http component to make API calls. The specific REST API I want to access returns a maximum of 100 Elements in one request. If more items exist, a hasMore flag is included in the response. To retrieve additional ...

How can we declare and showcase a generic object with an unspecified number and names of keys in React using TypeScript?

I am facing a challenge with objects that have a 'comments' field. While all the other fields in these different objects have the same types, the 'comment' field varies. I do not know the exact number or names of the keys that will be p ...

Updating a string in JavaScript by dynamically adding values from a JSON object

In my current function, I am making a request to fetch data and storing it as an object (OBJ). Afterwards, I make another request to get a new URL that requires me to update the URL with values from the stored data. The information saved in the object is ...

Having trouble dynamically adding elements to the Semantic-UI Accordion component

I have a challenge involving inserting dynamic content into a Semantic-UI Accordion. My goal is to display JSON data as an Accordion in the HTML. Below is the script and HTML I am using for this purpose: <script language='javascript'> ...

typescript api overlooking the async await functionality

My controller contains an asynchronous method that is supposed to set a results object. However, I'm facing an issue where instead of waiting for the 'await' to finish executing, the code jumps to the response object call prematurely, leavin ...