Exploring methods to clarify the type being utilized in TypeScript

I have a function that validates data for Kushki forms

export const validateKushkiForm = (type: KUSHKI_METHODS, kushkiData: KushkiCashType | 
KushkiTransferType)
 => {

    const errors = [];

    if (type === KUSHKI_METHODS.CASH) {
        !kushkiData.firstName && errors.push('firstName');
        !kushkiData.lastName && errors.push('lastName');
        !kushkiData.documentNumber && errors.push('documentNumber');
    } else if (type === KUSHKI_METHODS.TRANSFER) {
        !kushkiData.documentNumber && errors.push('documentNumber');
    }

    return errors;
};

For the type KushkiCashType, the properties include:

firstName: string;
lastName: string;
documentNumber: string;

For the type KushkiTransferType, it only has the property:

documentNumber: string; 
Error message: 'Property 'firstName' does not exist on type 'KushkiCashType | KushkiTransferType'.
  Property 'firstName' does not exist on type 'KushkiTransferType'.ts(2339)'

The issue arises because kushkiData can be of type KushkiCashType or KushkiTransferType. How can this error be resolved?

Answer №1

To determine the type, it is necessary to examine the object at hand. Establishing the type of b solely based on the value of a is not feasible.

One common approach is to define it as a property of the object:

type KushkiCashType = {
    type: 'cash';
    firstName: string;
    lastName: string;
    documentNumber: string;
}

type KushkiTransferType = {
    type: 'transfer';
    documentNumber: string; 
}

export const validateKushkiForm = (kushkiData: KushkiCashType | 
KushkiTransferType) => {
    const errors = [];

    if (kushkiData.type === 'cash') {
        !kushkiData.firstName && errors.push('firstName');
        !kushkiData.lastName && errors.push('lastName');
        !kushkiData.documentNumber && errors.push('documentNumber');
    } else if (kushkiData.type === 'transfer') {
        !kushkiData.documentNumber && errors.push('documentNumber');
    }

    return errors;
};

An alternative method closer to your original idea involves testing the properties of the object using in. In this scenario, distinguishing between types with and without firstName can be done through this check.

type KushkiCashType = {
    firstName: string;
    lastName: string;
    documentNumber: string;
}

type KushkiTransferType = {
    documentNumber: string; 
}

export const validateKushkiForm = (kushkiData: KushkiCashType | 
KushkiTransferType) => {

    const errors = [];

    if ("firstName" in kushkiData) {
        !kushkiData.firstName && errors.push('firstName');
        !kushkiData.lastName && errors.push('lastName');
        !kushkiData.documentNumber && errors.push('documentNumber');
    } else {
        !kushkiData.documentNumber && errors.push('documentNumber');
    }

    return errors;
};

Answer №2

If you're dealing with a situation like this, one approach you could take is to utilize type extension.

enum PAYMENT_METHODS {
  CASH,
  TRANSFER,
}

type CashPaymentType = {
  firstName: string
  lastName: string
  documentNumber: string
}
type TransferPaymentType = {
  documentNumber: string
}

export const validatePaymentForm = (
  method: PAYMENT_METHODS,
  paymentData: CashPaymentType & TransferPaymentType
) => {
  const errors: string[] = []

  if (method === PAYMENT_METHODS.CASH) {
    !paymentData.firstName && errors.push("firstName")
    !paymentData.lastName && errors.push("lastName")
    !paymentData.documentNumber && errors.push("documentNumber")
  } else if (method === PAYMENT_METHODS.TRANSFER) {
    !paymentData.documentNumber && errors.push("documentNumber")
  }

  return errors
}

TS playground

Answer №3

Develop a fresh concept that combines the qualities of both varieties.

type CombinedType = KushkiCashType | KushkiTransferType;

export const checkKushkiForm = (method: KUSHKI_METHODS, data: CombinedType) => {
....

It appears to be set up correctly, but here's a suggestion that could assist.

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

Error message: Issue with TypeScript and cleave.js - 'rawValue' property is not found on type 'EventTarget & HTMLInputElement'

I am encountering an error with the onChange event while implementing cleave in typescript. TypeScript is throwing an error indicating that 'rawValue' is not present in event.target. Here is my code: import React, { useCallback, useState, useEff ...

Using TypeScript to modify the attributes of an SCSS element

When working with SCSS, I am wondering how to modify an element's attribute. For instance: a1{ a2{ img{ top: 0; }}} If the .scss file is located in the same folder as the .ts file, how can I use Typescript to change the value from ...

Discovering the power of Angular 2 with ngrx while putting my Reducer to the

Within my Reducer file: case PumpActionTypes.EnterLocalMode: return commandOne.upsertOne( {id: action.payload.id, changes: { local: false }}, state ); When testing, I aim to verify that the local property is indeed modified to false. My curr ...

How can you typically verify the type of an object variable in TypeScript?

How can I verify if the obj variable contains all the properties defined in the Person interface? interface Person { name: string; age: number; } const jsonObj = `{ name: "John Doe", age: 30, }`; const obj: Person = JSON.parse(jsonObj); ...

Issues with Vercel's JavaScript Environment Variables Accessibility

I am encountering an issue trying to access environment variables on Vercel using JavaScript (TypeScript). Despite setting them under /settings/environment-variables, I receive undefined when attempting to access them with process.env.TURSO_DATABASE_URL du ...

Exploring the Depths of JSON Arrays within Typescript

I am faced with a challenge in extracting the value of the "id" from the following array of JSON data. The issue lies in the fact that the value is enclosed within double square brackets "[[" which are causing complications in retrieving the desired result ...

retrieve an object with enum keys that are indexed

I am faced with a situation where I have a collection of interdependent elements, each identified by a unique code (enumeration). My goal is to retrieve the list of elements that depend on a specific element, and then be able to reference them using myElem ...

Encountering an issue when attempting to save an excel file in Angular 8, receiving an error message that states "

When working with angular 8, I encountered an issue while trying to save an excel file. The error message displayed was as follows: ERROR TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed. at Functi ...

Create a Referral Program page within a swapping interface similar to the functionalities found in platforms like PancakeSwap, PantherSwap, and

Currently, my goal is to create a referral program page similar to the one found at . I have explored the source code on GitHub for the PantherSwap interface, but unfortunately, I did not come across any references to that specific section. Would you be ...

Guide for configuring a server to exclusively render Vue components

I have been utilizing the vue-no-ssr library (available at https://github.com/egoist/vue-no-ssr), but it only renders components on the client side. I require my component to render on the server side. Is there a method to create a vue component that exclu ...

Property of object (TS) cannot be accessed

My question relates to a piece of TypeScript code Here is the code snippet: export function load_form_actions() { $('#step_2_form').on('ajax:before', function(data) { $('#step_2_submit_btn').hide(); $(&ap ...

Incorrect deduction of the argument type for a higher-order function

If I wanted to create a function that takes an object of type T and another value, where the type P should somehow be restricted by T (for example, P should be an array of keys of T), I could easily write it like this: function customFunction<T, P exte ...

Make sure that the input for a function is a valid key within a specific interface, and that the corresponding value in the interface is

I'm a beginner in TypeScript and I've hit a roadblock with this issue. Despite searching extensively, I haven't found a solution yet. My goal is to create a well-typed sorting function that takes two parameters: an array of objects and the ...

Compilation error in VueJS: missing dependency detected

I am facing an issue in my VueJS project where a file I am referencing seems to be causing a compilation error. Despite being present in the node_modules directory, the dependency is declared as not found. In the image on the left, you can see the directo ...

Using a single Material Autocomplete input to handle two values within Angular

Looking to implement a search feature using Material's autocomplete that can filter by either user name or user ID. The current implementation is partially functional in this Stackblitz. When selecting a user name from the autocomplete options with a ...

Creating a declaration file for a library's entry point involves outlining the structure and types

I have developed an npm library that is made up of several ES6 modules, which are then consolidated into a single js file. The directory structure looks like this: src main.ts one.ts two.ts three.ts types index.d.ts index.ts The index.ts fil ...

TypeScript is unaware that a component receives a necessary prop from a Higher Order Component (HOC)

My component export is wrapped with a higher-order component (HOC) that adds a required prop to it, but TypeScript seems unaware that this prop has already been added by the HOC. Here's the Component: import * as React from "react"; import { withTex ...

Error encountered while downloading file from S3 on NextJs due to network issue

I have encountered a network error while trying to download a file from Amazon S3. Despite configuring my Amazon config file correctly and using the S3.getObjectURl() method for the download, it still fails. Below is the snippet of my code: const AWSDownlo ...

What's Going on with My Angular Dropdown Menu?

Snippet of HTML code: <li class="nav-item dropdown pe-3"> <a class="nav-link nav-profile d-flex align-items-center pe-0" (click)="toggleProfileMenu()"> <img src="assets/img/profile-img.jpg" alt=& ...

Transfer my testing utilities from React Router version 5 to version 6

I am currently transitioning my project to React V6 router and encountering an issue with my test utility function. Every time I run the test, all my expectations fail because jest cannot locate the object. Has anyone faced this error during a similar migr ...