Home > Software design >  How to make TypeScript understand which type i use
How to make TypeScript understand which type i use

Time:09-16

I have function

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;
};

in KushkiCashType next type

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

in KushkiTransferType

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

kushkiData can have KushkiCashType or KushkiTransferType how to fix this error?

CodePudding user response:

You have to determine the type based on the object in question. You can't determine the type of b from the value of a.

A typical approach would be to make it 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;
};

Keeping closer to what you have, you could test properties of the object with in. In this case, since one type has firstName and the other does not, you can check for that.

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;
};

CodePudding user response:

In this case you could use type extending

enum KUSHKI_METHODS {
  CASH,
  TRANSFER,
}

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

export const validateKushkiForm = (
  type: KUSHKI_METHODS,
  kushkiData: KushkiCashType & KushkiTransferType
) => {
  const errors: string[] = []

  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
}

TS playground

CodePudding user response:

Create a new definition that merges the two types together.

type NewType = KushkiCashType | KushkiTransferType;

export const validateKushkiForm = (type: KUSHKI_METHODS, kushkiData: NewType) => {
....

Seems like it should work the way that you have it but this might help.

  • Related