SolvedDefinitelyTyped @types/react-native don't work with typescript 3.1.1

Current typings produce very strange errors being used with typescript 3.1.1
I submit microsoft/TypeScript#27421 to typescript repo, but sure that DT also should track this issue. Main problem, that I can't create minimal example for this. And I can't personally understand why ts since 3.1 behave so strangely. It would be good if anyone can help with this.

Next is mostly duplication of info from microsoft/TypeScript#27421:

import React from 'react'
import { StyleSheet, Text } from 'react-native'

const s = StyleSheet.create({
  didNotWork: {
    fontSize: 16,
    fontWeight: '900', // if we comment this line, errors gone
    marginTop: 5, // if this line commented, errors also gone
  },
  work: {
    fontSize: 18,
//    fontWeight: '900', // when uncommented also work
  },
})

export const sample1 = <Text style={s.work} />
export const sample2 = <Text style={s.didNotWork} />
// ^ this line generate error:
// index.tsx:17:30 - error TS2322: Type 'RegisteredStyle<{ fontSize: number; fontWeight: string; marginTop: number; }>' is not assignable to type 'StyleProp<TextStyle>'.
//   Type 'RegisteredStyle<{ fontSize: number; fontWeight: string; marginTop: number; }>' is not assignable to type 'RecursiveArray<false | TextStyle | RegisteredStyle<TextStyle> | null | undefined>'.
//     Property 'length' is missing in type 'Number & { __registeredStyleBrand: { fontSize: number; fontWeight: string; marginTop: number; }; }'.
// 17 export const sample2 = <Text style={s.didNotWork} />
//                                 ~~~~~
//   node_modules/@types/react-native/index.d.ts:907:5
//     907     style?: StyleProp<TextStyle>;
//             ~~~~~
//     The expected type comes from property 'style' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Text> & Readonly<{ children?: ReactNode; }> & Readonly<TextProps>'
export const sample3 = <Text style={{fontSize: 16, fontWeight: '900', marginTop: 5}} />

This sample shows the error. There is sandbox repo: https://github.com/vovkasm/rn-ts-3.1.1 (to reproduce, clone and npm install && npm test)

  1. If I comment out fontWeight or marginTop style of didNotWork key, error dissapeared
  2. If I add fontWeight to work key, error dissapeared

Why is this?

17 Answers

✔️Accepted Answer

I'm currently working around this issue by casting. I feel doing this consistently will allow me to quickly find & replace to remove when it's addressed

<Image
      style={styles.closeButtonIcon as ImageStyle}
      source={require('resources/icons/png/x.png')}
/>

Other Answers:

@alloy I understand what docs says, but can prove that code:

const myStyle: ViewStyle = { flex: 1 }
export const FlexView: React.SFC = (props) => <View style={myStyle}>{props.children}</View>

has almost same performance (even slightly faster) compared to

const s = StyleSheet.create({ flex: { flex: 1 } })
export const FlexView: React.SFC = (props) => <View style={s.flex}>{props.children}</View>

because if you look at sources, you discover that latest chunk effectively extracted to this (see: https://github.com/facebook/react-native/blob/0.57-stable/Libraries/StyleSheet/StyleSheet.js#L373):

const s = { flex: { flex: 1 } }
export const FlexView = (props) => <View style={s.flex}>{props.children}</View>

And yes, in previous versions of RN it was global registry of styles, but it was even more slow, because it never crossed bridge border actually (proof from 0.55 branch) 😀

Our workaround is to type the Styles object, which will give you errors when you use the wrong type, but you have to be explicit about all the style rules, which is tedious:

import { StyleSheet, TextStyle, ViewStyle } from "react-native";

type Style = {
    container: ViewStyle;
    title: TextStyle;
    icon: ImageStyle;
};

export default StyleSheet.create<Style>({
    container: {
        flex: 1
    },
    title: {
        color: red
    },
    icon: {
        width: 10,
        height: 10
    }
});

@alloy seems like the docs are outdated. After landing facebook/react-native@a8e3c7f StyleSheet.create just returns the passed in object unaltered. The IDs used before are no more, ReactNativePropRegistry (StyleSheetRegistry) is gone.

Can someone make a pr to fix this based on this clarification

More Issues: