Skip to content
Advertisement

How to force a type in a variable : The property does not exist in the type ‘AllMatch | SingleMatch’ ts(2339)

I have an interface of this shape:

export interface Predicates{
    term?: Term,
    termMatcher?: TermMatcher
}

export interface Term {
    mainTerm: string,
    isNegativeTerm: boolean
}

export interface TermMatcher {
    value: SingleMatch | MultipleMatch,
    isNegativeMatcher: boolean
}

export interface SingleMatch {
    type: "singleMatch",
    value: string
}

export interface MultipleMatch {
    type: "multipleMatch",
    values: OneMatcherTerm[]
}

And I need to access the value field of the SingleMatch interface on a variable. To do this I use the following code:

import { OrDelimiter } from "./request.parser.model";

export function buildMonoExpressionSingleMatch(listExpressionsFromResquest: OrDelimiter, indexAnd: number, indexPredicates: number): any {
    const resultQuery: any = {};

    //here I cant't access to variable value
    const value: string = listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].termMatcher?.value?.value;

    //here the access to variable mainTerm works well
    const termName: string = listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].term?.mainTerm!;

    return resultQuery
}

export function buildMonoExpressionFromQuery(query: any, listExpressionsFromResquest: OrDelimiter): any {
  if (listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher?.value.type 
  === "singleMatch") {
    //here the access to variable value works well
    const value: string = 
      listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher.value.value ? 
      listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher.value.value : 
      "error";
  }
  
    buildMonoExpressionSingleMatch(listExpressionsFromResquest, 0, 0);
    return resultQuery;
}

In the buildMonoExpressionSingleMatch() function I can access my variable without error if I check before that the function is of the right type for index 0:

if (listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher?.value.type === "singleMatch") {
     const value: string = listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher?.value.value ? listExpressionsFromResquest.childAndArray[0].childPredicatesArray[0].termMatcher?.value.value : "error";
}

But if I do this check with the dynamic index I passed as a parameter (which I want to do):

if (listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].termMatcher?.value.type === "singleMatch") {
    const value: string = listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].termMatcher?.value.value ? listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].termMatcher?.value.value : "error";
}

I get an error that says:

Property 'value' does not exist on type 'AllMatch | SingleMatch | MultipleMatch | InitMatch'.
  Property 'value' does not exist on type 'MultipleMatch'.ts(2339)

How to tell the Typescript compiler: I know I’m in this type so this field must exist?

I tried adding a ! to my value field to remove undefined and null from my variable but the problem remained the same.

If you know how to get past this error tell me

If you see what I’m doing wrong it would help me a lot to get on the right track. Thank you in advance if you take the time to help me.

Advertisement

Answer

I found my answer, thanks to Dave Meehan’s comment.

By first retrieving my sub term, then reading the field I am interested in, I manage to read the field of my variable which can be of several different types.

The code looks like this:

export function buildMonoExpressionSingleMatch(listExpressionsFromResquest: OrDelimiter, indexAnd: number, indexPredicates: number): any {

    const resultQuery: any = {};

    let valueMatch: string = "";

    const value: SingleMatch = listExpressionsFromResquest.childAndArray[indexAnd].childPredicatesArray[indexPredicates].termMatcher?.value as SingleMatch;
    valueMatch = value.value;

    valueMatchTerm["value"] = valueMatch;
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement