Search code examples
javascripttypescriptstyled-componentsoptional-chaining

JavaScript optional chaining dynamic property


I am trying to access a dynamic property with safety provided by optional chaining that is available in TS. However it appears that this is not valid.

export const theme = {
  headers: {
    h1: {
    },
    h6: {
      color: '#828286'
    },
  },
}
console.info(theme?.headers?.['h6']?.color ?? '#000') //will pass
console.info(theme?.headers?.['h1']?.color ?? '#000') //will fail

Error

Identifier expected.  TS1003

    10 |   const StyledTypography = styled.div`
    11 |     margin: 0;
  > 12 |     color: #000; ${({theme}) => theme?.headers?.[variant]?.color ?? '#000'}
       |                                                ^
    13 |   `
    14 |   return (
    15 |     <StyledTypography as={variant}>

It appears that the optional changing will apply to the optional [] as a type but not to the values inside.

How can I make this optional without having to do [undefined || someDefaultValue]?


Solution

  • You can create an interface that maps your theme object and pass the compiler type checking.

    interface Headers {
        [key: string]: {
            [key: string]: string
        }
    }
    
    interface Theme {
        headers: Headers
    }
    
    const theme: Theme = {
      headers: {
        h1: {
        },
        h6: {
          color: '#828286'
        },
      },
    }
    console.info(theme?.headers?.['h6']?.color ?? '#000') //will pass
    console.info(theme?.headers?.['h1']?.color ?? '#000')