Home > database >  Extend existing object with conditional properties
Extend existing object with conditional properties

Time:10-18

I wonder how to deal with this example. There is declared object and I want to conditionally add properties to object. Is there any way to do it?


  let condition = true;
  
  const config = {
    ...otherProps,
    type: "date",
    variant: "outlined",
    fullWidth: true,
    InputLabelProps: {
      shrink: true,
    },
  };
  
 if (condition) {
    config.error = true;
    config.helperText = 'error';
  }

I've errors:

Property 'error' does not exist on type

Property 'helperText' does not exist on type

CodePudding user response:

If you don't assign a type with the initial assignment, then Typescript infers a type from the value at that point. Typescript does not look ahead and make other assignments part of that that type. This means that the type of config is locked in after it gets assigned to a value, and then you try to write unknown properties that aren't part of that type and get an error.


The quick fix is to make the conditional part of the initial assignment.

let condition = true;
  
const config = {
    type: "date",
    variant: "outlined",
    fullWidth: true,
    InputLabelProps: {
      shrink: true,
    },
    ...(condition ? { error: true, helperText: 'error' } : {})
}

config.error // (property) error?: boolean | undefined

Now typescript can properly infer that error and helperText exist and are optional.

See Playground


But a better solution is to make a proper type for this object. It seems like more work up front, but robust types will save you a lot of time and headache in the long run.

interface Config {
    type: 'date' | 'text' | 'whatever'
    variant?: 'outlined' | 'filled' | 'default'
    fullWidth?: boolean
    InputLabelProps: { shrink: boolean },
    error?: boolean
    helperText?: string
} // or something

let condition = true;

const config: Config = {
    type: "date",
    variant: "outlined",
    fullWidth: true,
    InputLabelProps: {
      shrink: true,
    },
}

if (condition) {
    config.error = true;
    config.helperText = 'error';
}

See playground

  • Related