Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface 'IconProps' incorrectly extends interface 'TouchableOpacityProps' #2888

Open
Tyrn opened this issue Jan 21, 2025 · 5 comments
Open
Labels

Comments

@Tyrn
Copy link

Tyrn commented Jan 21, 2025

Describe the bug

This is a typescript error on line 16 of file src/components/Icon.tsx.

import { ComponentType } from "react"
import {
  Image,
  ImageStyle,
  StyleProp,
  TouchableOpacity,
  TouchableOpacityProps,
  View,
  ViewProps,
  ViewStyle,
} from "react-native"
import { useAppTheme } from "@/utils/useAppTheme"

export type IconTypes = keyof typeof iconRegistry

interface IconProps extends TouchableOpacityProps {
  /**
   * The name of the icon
   */
  icon: IconTypes

  /**
   * An optional tint color for the icon
   */
  color?: string

  /**
   * An optional size for the icon. If not provided, the icon will be sized to the icon's resolution.
   */
  size?: number

  /**
   * Style overrides for the icon image
   */
  style?: StyleProp<ImageStyle>

  /**
   * Style overrides for the icon container
   */
  containerStyle?: StyleProp<ViewStyle>

  /**
   * An optional function to be called when the icon is pressed
   */
  onPress?: TouchableOpacityProps["onPress"]
}
...

The property in question is probably

  /**
   * Style overrides for the icon image
   */
  style?: StyleProp<ImageStyle>

The error message:

ts: Interface 'IconProps' incorrectly extends interface 'TouchableOpacityProps'.
  Types of property 'style' are incompatible.
    Type 'StyleProp<ImageStyle>' is not assignable to type 'StyleProp<ViewStyle>'.
      Type 'ImageStyle' is not assignable to type 'StyleProp<ViewStyle>'.
        Type 'ImageStyle' is not assignable to type 'ViewStyle'.
          Types of property 'transformOrigin' are incompatible.
            Type 'string | (string | number)[] | undefined' is not assignable to type 'string | undefined'.
              Type '(string | number)[]' is not assignable to type 'string'. [2430]

I never touched this file.

Ignite version

release

Additional info

?master ~/spaces/rn/IgniteTrivia> npx ignite-cli doctor
System
  platform           linux
  arch               x64
  cpu                12 cores       AMD Ryzen 5 5600G with Radeon Graphics
  directory          IgniteTrivia   /home/alexey/spaces/rn/IgniteTrivia

JavaScript (and globally-installed packages)
  node               22.13.0                                   /home/alexey/.local/share/mise/installs/node/22.13/bin/node
  npm                10.9.2                                    /home/alexey/.local/share/mise/installs/node/22.13/bin/npm
    corepack         0.30.0
    npm              10.9.2
  yarn               1.22.22                                   /home/alexey/.local/share/mise/installs/yarn/1/bin/yarn
  pnpm               9.12.3                                    /home/alexey/.local/share/mise/installs/pnpm/9.12.3/bin/pnpm
                     <no pnpm global package info available>
  bun                -                                         not installed
  expo               52.0.25                                   managed

Ignite
  ignite-cli         10.1.4       /home/alexey/.npm/_npx/e31027f3785124a8/node_modules/.bin/ignite
  ignite src         build        /home/alexey/.npm/_npx/e31027f3785124a8/node_modules/ignite-cli/build

Android
  java               17.0.13      /usr/bin/java
  android home       -            /opt/android-sdk

Tools
  git                git version 2.47.1   /usr/bin/git
?master ~/spaces/rn/IgniteTrivia>
@Tyrn Tyrn added the bug label Jan 21, 2025
@robinheinze
Copy link
Member

@Tyrn I'm not able to reproduce this in a freshly ignited app. Can you provide a link to a minimal reproduction app?

@Tyrn
Copy link
Author

Tyrn commented Jan 22, 2025

As you can guess, I'm struggling with the IgniteTrivia sample project, trying to recreate it from scratch. I dutifully saved the npx ignite-cli new output:

      npx ignite-cli new IgniteTrivia \
        --bundle=com.ignitetrivia \
        --git \
        --install-deps \
        --packager=npm \
        --target-path=/home/alexey/spaces/rn/IgniteTrivia \
        --remove-demo \
        --new-arch \
        --experimental=expo-router \
        --workflow=cng \
        --no-timeout=false \
        --state=mst

This way I created the project again; no error. Next step, I deleted the problematic project locally, then recreated it from my GitHub repo. No errors. Then

npm i
npx expo run:android

The app shows on my connected phone, everything's fine... And then the subject error. Fascinating, with the splash screen on my phone, the error in my editor window appears.

@vijit1018
Copy link

Use this updated code:

interface IconProps extends Omit<TouchableOpacityProps, "style"> {
/**

  • The name of the icon
    */
    icon: IconTypes

/**

  • An optional tint color for the icon
    */
    color?: string

/**

  • An optional size for the icon. If not provided, the icon will be sized to the icon's resolution.
    */
    size?: number

/**

  • Style overrides for the icon image
    */
    style?: StyleProp // Image-specific styles

/**

  • Style overrides for the icon container (TouchableOpacity)
    */
    containerStyle?: StyleProp // View-related styles

/**

  • An optional function to be called when the icon is pressed
    */
    onPress?: TouchableOpacityProps["onPress"]
    }

@Tyrn
Copy link
Author

Tyrn commented Jan 27, 2025

Thank you very much! Could you explain the nature of the update?

interface IconProps extends Omit<TouchableOpacityProps, "style">

NB The StyleProps shouldn't be changed (a typo, probably):

...
  /**
   * Style overrides for the icon image
   */
  style?: StyleProp<ImageStyle>

  /**
   * Style overrides for the icon container
   */
  containerStyle?: StyleProp<ViewStyle>
...

@vijit1018
Copy link

vijit1018 commented Feb 6, 2025

The update in this TypeScript interface is related to the extension of TouchableOpacityProps with an Omit<TouchableOpacityProps, "style"> operation.

What Changed?

  • Previously, IconProps might have directly extended TouchableOpacityProps, inheriting all of its props, including style.
  • Now, the Omit<TouchableOpacityProps, "style"> is used to remove the style property from TouchableOpacityProps before extending it.
  • A new custom style prop (StyleProp<ImageStyle>) is explicitly defined in IconProps.

Why This Change?

  1. Avoids Conflicts:

    • TouchableOpacityProps already has a style prop (StyleProp<ViewStyle>), which is meant for the touchable container.
    • In this case, IconProps introduces its own style prop (StyleProp<ImageStyle>) specifically for the icon image, which could otherwise conflict with the inherited style.
  2. Better Type Safety:

    • Ensures that style applies only to the image (not the container).
    • Prevents accidental passing of ViewStyle properties to the icon image, which may cause UI issues.
  3. Separation of Concerns:

    • A separate containerStyle?: StyleProp<ViewStyle> is added to handle styles for the touchable container.
    • This makes it clear that style is for the icon image, while containerStyle is for the surrounding touchable wrapper.

Final Behavior

  • style: Applies to the icon image (ImageStyle).
  • containerStyle: Applies to the icon container (TouchableOpacity) (ViewStyle).
  • TouchableOpacityProps is inherited without its style property.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants