4

Let us say that I have a react native native UI component like the one in this example. How do I create a typescript type definition for it, like the ones that can be imported, for example with 'npm i @types/somelib'? I didn't find explanations about how to do this in the documentation.

The idea is to be able to use the native component seamlessly in a react-native typescript project and for that I need to create the type definition for native components. So, how do I create typescript type definitions for native components?

The iOS/objc side

  • FoobarView.h:

    #ifndef FoobarView_h
    #define FoobarView_h
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    @interface FoobarView : UITextView
    @property (nonatomic, assign) BOOL teste;
    @end
    #endif

  • FoobarView.m:

    #import "FoobarView.h"
    @implementation FoobarView
    -(void) setTeste:(BOOL)teste
    {
      if (teste == YES)
      {
        [self setText:@"é true"];
      }else
      {
        [self setText:@"é false"];
      }
    }
    -(BOOL)getTeste
    {
      if ([[self text] isEqual:@"é true"])
      {
        return YES;
      }else
      {
        return NO;
      }
    }
    @end

  • FoobarManager.m

    #import <Foundation/Foundation.h>
    #import <React/RCTViewManager.h>
    #import "FoobarView.h"
    @interface FooManager : RCTViewManager
    @end
    @implementation FooManager
    RCT_EXPORT_MODULE(FoobarView)
    RCT_EXPORT_VIEW_PROPERTY(teste, BOOL)
    +(BOOL) requiresMainQueueSetup
    {
      return YES;
    }
    - (UIView*)view
    {
      FoobarView *v = [[FoobarView alloc]init];
      return v;
    }
    @end

So, FoobarView is a native iOS view, written in objc. It is not a react native ui component. I am using a simple descendent from UITextView but it could be anything, like a SceneKit view.

To use it in the javascript side of react native, I'm using this code in FoobarView.js:

import { requireNativeComponent } from 'react-native';
module.exports = requireNativeComponent('FoobarView');

And, finally, i can use FoobarView in a render block:

    <FoobarView style={{width:'100%', height:30}} teste={true} />

My question is: How can I define that FoobarView, something defined in the ios, has the property teste, and that teste is a boolean?

6
  • I will look it up shortly but why don't just write the component in typescript? Or is it not in your power to decide if the project is in js or ts? Commented Nov 25, 2019 at 18:47
  • @Elias It's a native component, written in objective-c. Commented Nov 25, 2019 at 19:48
  • edited my answer. Should not be too different Commented Nov 25, 2019 at 20:58
  • How about a react-native native PureComponent how native are we going to get :D Commented Nov 25, 2019 at 20:58
  • The reason I am insisting on writing native ui components (that is, UIViews that react native can understand and use to assemble the view) is that there is no 3d library for RN that is flexible && works on RN 0.6x. So I decided to write my own, for my own proposes, and to do so, I must understand how to create native ui views. Commented Dec 1, 2019 at 0:35

2 Answers 2

5

I guess for the topic starter my answer is a bit late but for everyone else who's facing the same issue I solved it with this approach:

import { requireNativeComponent, HostComponent } from 'react-native';

// Specify all your properties
interface Props {
  teste: boolean;
}

const FoobarView: HostComponent<Props> = requireNativeComponent('FoobarView');

module.exports = FoobarView;

TS will recognize only teste property but in your example you also pass style property to the component, so in order to support it as well you should either specify it explicitly in the Props above, e.g.

interface Props {
  teste: boolean;
  style: ViewStyle;
}

Or you can extend View properties (if they're suitable for your usecase), e.g.

interface Props extends ViewProps {
  teste: boolean;
}
Sign up to request clarification or add additional context in comments.

2 Comments

I am using react-native 0.61.4 but HostComponent doesn't resolve in 'react-native'.
@Rishabh876 HostComponent shoud be available from v0.62 and higher
0

For React native versions below 0.62

Make sure to create .tsx file like this.

//FoobarView.tsx

import React, { ReactElement } from 'react'
import { requireNativeComponent, ViewProps } from 'react-native'

interface Props extends ViewProps {
    teste: boolean
}
const _FoobarView = requireNativeComponent('FoobarView')

const FoobarView = (props: Props): ReactElement<Props> => {
    return <_FoobarView {...props} style={props.style} />
}

export default FoobarView

Inspired from: https://shopify.engineering/creating-native-components-accept-react-native-subviews

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.