Using Typescript to create mapped types with optional parameters

I am currently working on implementing a mapped type that has some required parameters and some optional ones.

While I have successfully implemented the required parameters, I am facing issues with utilizing the optional ones.

type Foo = { foo: string }

const A_FIELD_REQ = ['x', 'y'] as const
const A_FIELD_OPT = ['z'] as const

const B_FIELD_REQ = ['x', 'y', 'z'] as const
const B_FIELD_OPT = [] as const

type QueryA = {
  type: 'a'
  fields: { [field in typeof A_FIELD_REQ[number]]: Foo | undefined }
}

type QueryB = {
  type: 'b'
  fields: { [field in typeof B_FIELD_REQ[number]]: Foo | undefined }
}

type Query = {
  id: string
} & (QueryA | QueryB)

const myQueries: Query[] = [
  {
    id: '0',
    type: 'a',
    fields: {
      x: { foo: '' },
      y: { foo: '' },
    },
  },
  {
    id: '1',
    type: 'a',
    fields: {
      x: undefined, // valid
      y: { foo: '' },
    },
  },
  {
    id: '2',
    type: 'b',
    fields: {
      x: { foo: '' },
      y: { foo: '' },
      z: { foo: '' },
    },
  },
]

Modifying my types

My goal is to be able to include optional parameters within the same key fields of my Query type, similar to a basic z?: Foo | undefined.

const myQueries = [
  {
    id: '0',
    type: 'a',
    fields: {
      x: { foo: '' },
      y: { foo: '' },
    },
  },
  {
    id: '1',
    type: 'a',
    fields: {
      x: undefined, // valid
      y: { foo: '' },
    },
  },
  {
    id: '2',
    type: 'b',
    fields: {
      x: { foo: '' },
      y: { foo: '' },
      z: { foo: '' },
    },
  },
  {
    id: '3',
    type: 'a',
    fields: {
      x: { foo: '' },
      y: { foo: '' },
      z: { foo: '' }, // !!! optional parameter !!!
    }
  }
]

Answer №1

Simply include the ? optional modifier

type QueryA = {
  type: 'a'
  fields: { [field in typeof A_FIELD_REQ[number]]?: Foo }
}

type QueryB = {
  type: 'b'
  fields: { [field in typeof B_FIELD_REQ[number]]?: Foo }
}

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

What is the proper way to define an array of objects in TypeScript?

In search of a way to define a function that accepts an array of unspecified object types, known as "anonymous types." I want to enforce strict typing with TypeScript. The objects in the array all have properties like name, price, and description. bagTotal ...

Navigating any object array in TypeScript and retrieving its properties

Consider the following JSON data object: var dataObjects = [ { "Name": "Date & Time", "Type": "Date", "Value": "2019-12-11" }, { "Name": "Activity", "Type": "String", ...

The global CSS styles in Angular are not being applied to other components as expected

Currently utilizing Angular v10, I have a set of CSS styles that are meant to be used across the entire application. To achieve this, I added them to our global styles.css file. However, I'm encountering an issue where the CSS is not being applied to ...

Incorrect positioning of AnyChart within a reusable component (Angular version 9.1.3, Bootstrap 4.4.1, Anychart version 8.7.1) causing display issues on the DOM

I have created a test dashboard featuring two Bootstrap cards, each containing an Anychart column chart. The primary objective is to experiment with reusable components. For those interested, here is the code link on Stackblitz Upon running the code, my ...

Unable to locate module, encountered a webpack alias issue while using typescript and react

I'm currently in the process of setting up aliases in webpack. My goal is to make importing components in App.js easier by replacing: ./components/layout/Header/Header with: @components/layout/Header/Header This way, I can avoid potential issues w ...

The tslint exclusion is not functioning properly for tsoa endpoints

I'm trying to remove the routes.ts file generated by tsoa routes from being compiled by tslint. I've used the exclude option but it doesn't seem to be working specifically for routes.ts. The exclude option works for other files, except for r ...

Encountering an Issue with Typings Installation in Angular 2 and Algolia Search

Struggling to integrate Algolia Search with my Angular 2 app, I've been following the installation guide at https://github.com/algolia/algoliasearch-client-javascript#install. However, when I run typings install algoliasearch-client-javascript --save ...

Trouble with Angular 7: Form field not displaying touched status

I am encountering an issue while trying to input data into a form, as it is not registering the touched status. Consequently, an error always occurs when attempting to send a message back to the user. In my TypeScript file, I am utilizing FormBuilder to c ...

Updating non-data properties dynamically in a custom AG Grid cell renderer

In my grid setup, I have implemented an editor button in a column for each row and a new item creator button outside the grid. One of the requirements is that all buttons should be disabled when either the create or edit button is clicked. To achieve thi ...

Tips for adding a "Select All" feature to a dropdown list?

Currently, I have a dropdown list with a filter for IN and OUT values. The functionality is working as expected: <select class="form-select" style="max-width: 100px" [ngModel]="selectedBrand" (ngModelChange)="onChangeT ...

How to format a Date object as yyyy-MM-dd when serializing to JSON in Angular?

I have a situation where I need to display an object's 'birthDate' property in the format DD/MM/YYYY on screen. The data is stored in the database as YYYY-MM-DD, which is a string type. I am currently using bootstrap bsDatePicker for this ta ...

A special term in Typescript that consistently points to the present object within the class

Is it feasible to utilize a reference to the current instance of a class in Typescript, similar to "this" in C# and Java, rather than the typical binding context interpretation in JavaScript? ...

Is there a way to access the element reference of a component directly within the template?

When I mouse over certain elements, I use the following code to set focus: <div #divTemplateVar (mouseover)="divTemplateVar.focus()"></div> However, this method does not work for components: <component #componentTemplateVar (mouseover)="c ...

experimenting with asynchronous promises in Jasmine to test Angular 2 services

Currently, I'm facing some challenges while testing my Angular 2 service. Even though my tests are passing, I keep encountering this error in the console: context.js:243 Unhandled Promise rejection: 'expect' was used when there was no c ...

Error: Unable to initialize i18next as a function

For my current project, I am utilizing TypeScript and i18next for internalization. TypeScript version: 2.1.4 i18next version: 2.3.4 @types/i18next version: 2.3.35 In the specific file: import * as i18next from 'i18next'; i18next.init({ ...

Guide to utilizing @types/node in a Node.js application

Currently, I am using VSCode on Ubuntu 16.04 for my project. The node project was set up with the following commands: npm init tsc --init Within this project, a new file named index.ts has been created. The intention is to utilize fs and readline to read ...

There seems to be an issue with the compatibility between typescript and the current version (4.17.14) of the express-serve-static

Using "@types/express-serve-static-core": "4.17.13", the augmentation of express-serve-static-core is functioning properly: import { Request, Response, NextFunction } from 'express' import { PrismaClient } from '@prisma/c ...

Is the regex returning the correct result?

I need to discuss the date field with a format of YYYYMMDD, as shown below: zod.string().max(8).regex(new RegExp('^(19[0-9][0-9]|20[0-9][0-9]|[0-1][0-9]{3})(1[0-2]|0[1-9])(3[01]|[0-2][1-9]|[12]0)$')); The value provided is 20001915. The definit ...

What steps do I need to take to ensure my TypeScript module in npm can be easily used in a

I recently developed a module that captures keypressed input on a document to detect events from a physical barcode reader acting as a keyboard. You can find the source code here: https://github.com/tii-bruno/physical-barcode-reader-observer The npm mod ...

Using Angular2, you can dynamically assign values to data-* attributes

In my project, I am looking to create a component that can display different icons based on input. The format required by the icon framework is as follows: <span class="icon icon-generic" data-icon="B"></span> The data-icon="B" attribute sp ...