nandorojo / dripsy

🍷 Responsive, unstyled UI primitives for React Native + Web.
https://dripsy.xyz
MIT License
2.04k stars 81 forks source link

@expo/html types errors #67

Closed nandorojo closed 3 years ago

nandorojo commented 3 years ago

I'm weirdly getting this error again. Seems like something changed with React's types, since I'm getting this after upgrading to Expo SDK40:

Type '{ children: string; }' is not assignable to type '(IntrinsicAttributes & Pick<StyledProps<TextProps>, "style" | "sx" | "themeKey" | "variant" | "variants" | "as" | "webContainerSx"> & Pick<...> & WebTextProps & RefAttributes<...>) | (IntrinsicAttributes & ... 4 more ... & RefAttributes<...>)'.
  Type '{ children: string; }' is missing the following properties from type 'Pick<TextProps & ClassAttributes<typeof Text>, "onLayout" | "testID" | "nativeID" | "accessible" | "accessibilityActions" | "accessibilityLabel" | ... 29 more ... | "accessibilityTraits">': accessibilityComponentType, accessibilityTraits

56       <H3>{title}</H3>

I think we need to add a { children?: React.ReactNode } to the return type of createThemedComponent...not sure. Will investigate this more. Using dripsy@1.4.6

nandorojo commented 3 years ago

Hmm, inspecting the types output from dripsy, this is already the case:

export declare const H3: import("react").ForwardRefExoticComponent<(Pick<import("../css/types").StyledProps<import("@expo/html-elements/build/primitives/Text").TextProps>, "sx" | "style" | "themeKey" | "variant" | "variants" | "as" | "webContainerSx"> & Pick<import("react-native").TextProps & import("react").ClassAttributes<typeof rText>, "ref" | "key" | "onLayout" | "testID" | "nativeID" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityComponentType" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityTraits" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "onTextLayout" | "onPress" | "onLongPress" | "maxFontSizeMultiplier" | "adjustsFontSizeToFit" | "minimumFontScale" | "suppressHighlighting" | "selectable" | "selectionColor" | "textBreakStrategy"> & import("@expo/html-elements/build/primitives/Text").WebTextProps & import("react").RefAttributes<import("react").ComponentType<import("@expo/html-elements/build/primitives/Text").TextProps>>) | (Pick<import("../css/types").StyledProps<import("@expo/html-elements/build/primitives/Text").TextProps>, "sx" | "style" | "themeKey" | "variant" | "variants" | "as" | "webContainerSx"> & Pick<import("react-native").TextProps & import("react").ClassAttributes<typeof rText>, "ref" | "key" | "onLayout" | "testID" | "nativeID" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityComponentType" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityTraits" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "allowFontScaling" | "ellipsizeMode" | "lineBreakMode" | "numberOfLines" | "onTextLayout" | "onPress" | "onLongPress" | "maxFontSizeMultiplier" | "adjustsFontSizeToFit" | "minimumFontScale" | "suppressHighlighting" | "selectable" | "selectionColor" | "textBreakStrategy"> & import("@expo/html-elements/build/primitives/Text").WebTextProps & {
    children?: import("react").ReactNode;
} & import("react").RefAttributes<import("react").ComponentType<import("@expo/html-elements/build/primitives/Text").TextProps>>)>;

That's gibberish, but it shows that children is indeed there. I'm not sure what could be causing this.

nandorojo commented 3 years ago

Is it possible React.ReactNode doesn't accept a string anymore? That wouldn't make sense.

cmaycumber commented 3 years ago

Is it possible React.ReactNode doesn't accept a string anymore? That wouldn't make sense.

That's an interesting hypothesis, that would make since.

nandorojo commented 3 years ago

Yeah, it just seems like such an odd decision, and I would expect it to happen to other components, too. The HTML elements have had a number of issues, oddly.

This is my package.json. I'm a bit stumped.

{
  "main": "__generated__/AppEntry.js",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "yarn local",
    "eject": "expo eject",
    "build": "NODE_OPTIONS=--max_old_space_size=8192 next build",
    "local": "node local.js && NODE_OPTIONS=--max_old_space_size=8192 next --hostname 0.0.0.0",
    "lint": "eslint src --ext .ts,.tsx",
    "lint:fix": "npm run lint -- --fix",
    "serve": "yarn next start --hostname 0.0.0.0 -p 4000",
    "postinstall": "expo-yarn-workspaces postinstall",
    "analyze": "EXPO_WEB_DEBUG=true ANALYZE=true yarn build",
    "customserver": "NEXT_PUBLIC_OPEN_API_ENDPOINT=http://192.168.1.136:8000 yarn local",
    "localcustomserver": "NEXT_PUBLIC_OPEN_API_ENDPOINT=http://0.0.0.0:8000 yarn local",
    "speed": "yarn analyze && next start"
  },
  "dependencies": {
    "@babel/runtime": "^7.0.0",
    "@beatgig/analytics": "*",
    "@beatgig/api": "*",
    "@beatgig/api-hooks": "*",
    "@beatgig/api-services": "*",
    "@beatgig/auth-hooks": "*",
    "@beatgig/calendar-embed": "*",
    "@beatgig/calendars": "*",
    "@beatgig/components": "*",
    "@beatgig/constants": "*",
    "@beatgig/design": "*",
    "@beatgig/forms": "*",
    "@beatgig/helpers": "*",
    "@beatgig/hooks": "*",
    "@beatgig/navigation": "*",
    "@beatgig/next-pages": "*",
    "@beatgig/payments": "*",
    "@beatgig/providers": "*",
    "@beatgig/screens": "*",
    "@beatgig/search": "*",
    "@beatgig/theme": "*",
    "@beatgig/ui": "*",
    "@beatgig/vendors": "*",
    "@date-io/date-fns": "1.x",
    "@expo/html-elements": "^0.0.1",
    "@expo/vector-icons": "^12.0.0",
    "@fullcalendar/core": "^5.4.0",
    "@fullcalendar/daygrid": "^5.4.0",
    "@fullcalendar/interaction": "^5.4.0",
    "@fullcalendar/list": "^5.4.0",
    "@fullcalendar/luxon": "^5.4.0",
    "@fullcalendar/moment-timezone": "^5.4.0",
    "@fullcalendar/react": "^5.4.0",
    "@fullcalendar/timegrid": "^5.5.0",
    "@material-ui/core": "^4.11.0",
    "@material-ui/pickers": "^3.2.10",
    "@module-federation/next-transpile-modules": "^4.2.1",
    "@nandorojo/swr-firestore": "^0.13.2",
    "@next/bundle-analyzer": "^9.5.3",
    "@popperjs/core": "^2.5.4",
    "@react-native-async-storage/async-storage": "^1.13.2",
    "@react-native-community/datetimepicker": "^3.0.4",
    "@react-native-community/masked-view": "0.1.10",
    "@react-native-community/netinfo": "5.9.7",
    "@react-native-community/slider": "^4.0.0-rc.2",
    "@react-native-picker/picker": "1.9.2",
    "@react-navigation/native": "^5.7.3",
    "@react-navigation/stack": "^5.9.0",
    "@react-spring/native": "^9.0.0-rc.3",
    "@segment/snippet": "^4.13.1",
    "@sentry/browser": "^5.25.0",
    "@sentry/node": "^5.25.0",
    "@sentry/webpack-plugin": "^1.13.0",
    "@theme-ui/color": "^0.4.0-rc.5",
    "@types/lodash": "^4.14.161",
    "@types/lodash.get": "^4.4.6",
    "@types/lodash.last": "^3.0.6",
    "@types/lodash.orderby": "^4.6.6",
    "@vvo/tzdb": "^6.3.0",
    "@welldone-software/why-did-you-render": "^6.0.5",
    "@zeit/next-source-maps": "^0.0.4-canary.1",
    "algoliasearch": "^4.4.0",
    "cloudinary-tiny-js": "^1.0.0",
    "color": "^3.1.3",
    "date-fns": "^2.16.1",
    "drift-js": "^0.0.0",
    "dripsy": "^1.4.6",
    "expo": "^40.0.0",
    "expo-analytics-segment": "~9.1.0",
    "expo-asset": "~8.2.0",
    "expo-blur": "~8.2.0",
    "expo-clipboard": "^1.0.1",
    "expo-font": "~8.4.0",
    "expo-image-manipulator": "~8.3.0",
    "expo-linear-gradient": "~8.3.0",
    "expo-network": "~2.3.0",
    "expo-next-react-navigation": "^1.2.1",
    "expo-progress": "^0.0.2",
    "expo-status-bar": "~1.0.2",
    "expo-video": "^1.0.2",
    "expo-web-browser": "~8.5.0",
    "firebase": "7.9.0",
    "firebase-admin": "^9.1.1",
    "framer-motion": "^2.9.4",
    "glsl-shader-loader": "^0.1.6",
    "highlight-words-core": "^1.2.2",
    "imagemin-optipng": "^8.0.0",
    "intercom-react": "^1.0.0-alpha.6",
    "lodash.get": "^4.4.2",
    "lodash.last": "^3.0.0",
    "lodash.orderby": "^4.6.0",
    "lodash.set": "^4.3.2",
    "logrocket": "^1.0.14",
    "lottie-react-native": "~2.6.1",
    "luxon": "^1.25.0",
    "mapbox-gl": "^2.0.1",
    "moment": "^2.18.1",
    "moment-timezone": "^0.5.32",
    "next": "^10.0.1",
    "next-circular-dependency": "^1.0.1",
    "next-compose-plugins": "^2.2.0",
    "next-fonts": "^1.4.0",
    "next-images": "^1.6.0",
    "next-optimized-images": "^2.6.2",
    "next-seo": "^4.15.0",
    "next-transpile-modules": "^4.1.0",
    "numeral": "^2.0.6",
    "postinstall-postinstall": "^2.1.0",
    "react": "16.13.1",
    "react-cache": "^2.0.0-alpha.1",
    "react-cool-img": "^1.2.5",
    "react-datepicker": "^3.3.0",
    "react-dates": "21.8.0",
    "react-dom": "16.13.1",
    "react-driftjs": "^1.1.11",
    "react-fast-compare": "^3.2.0",
    "react-fullstory": "^1.4.0",
    "react-intersection-observer": "^8.30.3",
    "react-mapbox-gl": "^5.1.1",
    "react-merge-refs": "^1.1.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-animatable": "^1.3.3",
    "react-native-doorman": "^1.4.0",
    "react-native-gesture-handler": "~1.7.0",
    "react-native-google-places-autocomplete": "^2.1.1",
    "react-native-maps": "0.27.1",
    "react-native-masked-text": "^1.13.0",
    "react-native-modal-datetime-picker": "^9.0.0",
    "react-native-notifier": "^1.3.2",
    "react-native-picker-select": "8.0.3",
    "react-native-popover-view": "^3.1.1",
    "react-native-reanimated": "2.0.0-rc.0",
    "react-native-redash": "^14.2.4",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.2",
    "react-native-shared-element": "0.7.0",
    "react-native-skeleton-content": "^1.0.20",
    "react-native-web": "^0.14.10",
    "react-native-web-hooks": "3.0.1",
    "react-native-web-lottie": "^1.4.4",
    "react-native-web-maps": "^0.3.0",
    "react-native-webview": "10.7.0",
    "react-navigation": "^4.4.0",
    "react-navigation-heavy-screen": "^1.0.2",
    "react-navigation-shared-element": "^3.0.0",
    "react-navigation-stack": "^2.8.2",
    "react-plaid-link": "^3.0.0",
    "react-spring": "^8.0.27",
    "react-typed": "^1.2.0",
    "react-use": "^15.3.8",
    "react-with-direction": "^1.3.1",
    "react-with-styles-interface-aphrodite": "^6.0.1",
    "recyclerlistview": "^3.0.0",
    "resize-observer-polyfill": "^1.5.1",
    "sentry-expo": "^2.1.2",
    "setimmediate": "^1.0.5",
    "smoothscroll-polyfill": "^0.4.4",
    "swr": "^0.3.2",
    "the-platform": "^0.10.1",
    "tippy.js": "^6.2.7",
    "yup": "^0.29.3"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "@expo/next-adapter": "^2.1.25",
    "@expo/webpack-config": "~0.12.45",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.4.1",
    "@types/algoliasearch": "^3.34.10",
    "@types/color": "^3.0.1",
    "@types/highlight-words-core": "^1.2.0",
    "@types/intercom-web": "^2.8.10",
    "@types/lodash.sortby": "^4.7.6",
    "@types/luxon": "^1.25.0",
    "@types/numeral": "^0.0.28",
    "@types/plaid-link": "^2.0.7",
    "@types/react-datepicker": "^3.1.1",
    "@types/react-dates": "^21.8.0",
    "@types/react-native": "~0.63.2",
    "@types/react": "16.13.1",
    "@types/segment-analytics": "^0.0.32",
    "@types/yup": "^0.29.7",
    "babel-plugin-transform-require-ignore": "^0.1.1",
    "eslint-config-nando": "^1.1.0",
    "husky": "^4.3.0",
    "patch-package": "^6.2.2",
    "prettier": "^2.1.2",
    "stripe": "^8.127.0",
    "typescript": "^4.1.1-rc",
    "webpack-hot-middleware": "^2.25.0"
  },
  "private": true,
  "resolutions": {
    "@theme-ui/core": "0.4.0-rc.1",
    "@theme-ui/css": "0.4.0-rc.1",
    "@theme-ui/mdx": "0.4.0-rc.1"
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn tsc",
      "pre-push": "# yarn analyze"
    }
  }
}
cmaycumber commented 3 years ago

Were you able to publish the latest version of the monorepo? The types should be working in it, I'm curious if they work for you as well. We might be able to reverse engineer the typescript config to find the setting causing the issue.

If the React.ReactNode is the issue and it works for you I'd be pretty intrigued why changing the typescript settings would force it to work.

nandorojo commented 3 years ago

I haven't published it yet, I've been pulling my hair out a bit trying to get my app to be compatible with Expo SDK 40. It seems like the upgrade may have messed with my lock file or something and installed a bunch of random stuff.

I can see if pushing the monorepo and installing that works.

cmaycumber commented 3 years ago

I haven't published it yet, I've been pulling my hair out a bit trying to get my app to be compatible with Expo SDK 40. It seems like the upgrade may have messed with my lock file or something and installed a bunch of random stuff.

I feel your pain...

I've been dealing with a babel issue on and off for the last day or so.

nandorojo commented 3 years ago

Yeah, I've also had a perennial Babel issue lately, where running next build gets hung up at my babel file for like 8 minutes, even though I only have Expo's babel config there. No idea...

For now, I'm hoping I can just get yarn tsc to work without Dripsy getting upset.

I have to admit, this one is really confusing me. Something seems up with React.ReactNode or createThemedComponent. Weirdly, it's all good with the dripsy-exported View:

Example

(Ignore this, fixed in next comment)

Here's an example of a FormRow component I'm making, where I explicitly cast the types:

Screen Shot 2021-01-24 at 6 55 51 PM

And yet, this error:

Screen Shot 2021-01-24 at 6 56 16 PM

Meanwhile, no issue for View imported from Dripsy:

Screen Shot 2021-01-24 at 6 56 08 PM
nandorojo commented 3 years ago

Ah, well removing the cast fixed the above one, so ignore that, haha.

The issue really comes down to the @expo/html-elements re-exports.

nandorojo commented 3 years ago

@cmaycumber Let me know what you think we should do with the merge conflicts on the yarn workspaces branch and I can publish that one

nandorojo commented 3 years ago

Okay so one very ugly bandaid fix I have is to edit the .d.ts output from Dripsy, and make the props optional by wrapping them with Partial. Interestingly my TS is raising errors for similar props issues passed to react-native-paper and react-native-elements. The errors are super opaque, it's a bit confusing still...

nandorojo commented 3 years ago

It seems like children is not the issue. Rather, it makes all props of a given component required, including optional ones...

nandorojo commented 3 years ago

Okay, I identified the issue.

For some reason, the react native TextProps are now requiring two props: accessibilityComponentType & accessibilityTraits. No idea why. I tried downgrading versions of @types/react-native to no avail.

However, with some declaration merging, I was able to solve it by just making them optional.

All you need to do is put this TS file anywhere in your app:

// dripsy-hack.d.ts
import 'react-native'

declare module 'react-native' {
  // fix HTML elements 
  interface TextProps {
    accessibilityComponentType?: string
    accessibilityTraits?: string
  }
  // pressable type support
  interface PressableStateCallbackType {
    hovered?: boolean
    focused?: boolean
  }
  // transition support in view props
  interface ViewStyle {
    transitionProperty?: string
    transitionDuration?: string
  }
}
nandorojo commented 3 years ago

Related: https://github.com/facebook/react-native/issues/24016, https://github.com/callstack/react-native-paper/issues/1962