How to extend a native's component's props TypeScript interface in a stateless, functional component in React Native?
Asked Answered
S

2

15

For consistent styling, the React Native docs recommend writing a <CustomText /> text component that wraps the native <Text /> component.

While this is easy to do, I can't work out with TypeScript 2 how to make <CustomText /> have all of the props from <Text /> without having to redeclare them.

Here's my component:

import React from 'react';
import { Text } from 'react-native';


interface Props {
    children?: any
}

const CustomText: React.SFC<Props> = (props) => (
    <Text {...props}>
        {props.children}
    </Text>
);

And if I try to use it with <CustomText numberOfLines={1} /> it will result in an error

TS2339: Property 'numberOfLines' does not exist on type 'IntrinsicAttributes & Props'

In react-native.d.ts, I see that there's this export:

export interface TextProperties extends React.Props<TextProperties> {

    /**
     * Specifies should fonts scale to respect Text Size accessibility setting on iOS.
     */
    allowFontScaling?: boolean

    /**
     * Line Break mode. Works only with numberOfLines.
     * clip is working only for iOS
     */
    lineBreakMode?: 'head' | 'middle' | 'tail' | 'clip'

    /**
     * Used to truncate the text with an elipsis after computing the text layout, including line wrapping, such that the total number of lines does not exceed this number.
     */
    numberOfLines?: number

    /**
     * Invoked on mount and layout changes with
     *
     * {nativeEvent: { layout: {x, y, width, height}}}.
     */
    onLayout?: ( event: LayoutChangeEvent ) => void

    /**
     * This function is called on press.
     * Text intrinsically supports press handling with a default highlight state (which can be disabled with suppressHighlighting).
     */
    onPress?: () => void

    /**
     * @see https://facebook.github.io/react-native/docs/text.html#style
     */
    style?: TextStyle

    /**
     * Used to locate this view in end-to-end tests.
     */
    testID?: string
}

but I'm not sure how to extend it to take advantage of it in my component's Props interface.

Smallscale answered 27/10, 2016 at 23:25 Comment(0)
C
25

You just need to make your Props interface extends TextProperties:

interface Props extends TextProperties {
    children?: any
}

Edit

You need to import it first:

import { Text, TextProperties } from 'react-native';
Curable answered 27/10, 2016 at 23:46 Comment(3)
I tried that, but it errors with TS2304: Cannot find name 'TextProperties'. Even tried adding the <reference path /> to no avail :(Smallscale
Check my revised answerCurable
Try, import { TextProps } from 'react-native' rather than, TextProperties.Severen
H
1
import { StyleSheet, Text, TextProps } from 'react-native'

export default function MText({ children, style }: TextProps) {
  return <Text style={[styles.text, style]}>{children}</Text>
}

const styles = StyleSheet.create({
  text: {
    fontFamily: 'OpenSans',
  },
})
Harleigh answered 21/2 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.