Hi! Is it possible to implement React Native components with TypeScript?
What I want to be able to do is this:
import React = require('react-native');
class MyClass<P, S> extends React.Component<P, S> { ... }
I figured I might need to create a type definition file for React Native (like the one for React.js). Is there any reason why nobody has created this file yet?
Wold love to see how we can use react native with typescript as well.
+1
We're focused on flow instead of typescript because it is a much more powerful tool for inferring program structure and verifying correctness, so I don't think we have any plans to support typescript at this time.
More info on flow: http://flowtype.org/
@sahrens Do you have any examples or specific cases where flow's type inference comes out ahead of Typescript? The only place Typescript is mentioned on http://flowtype.org/ is about future plans for adding support for converting existing TypeScript declaration files. I am having a hard time identifying any advantage of using flow instead of Typescript. Thx!
@bparadie a big advantage is that flow is more like a linter than a compiler. if you ask in the flow IRC chat i'm sure you'll get some good responses.
@sahrens Thanks for the clarification! Just to make it clear: It is theoretically possible to use React Native with TypeScript if I define the definition file, right? (Or would it somehow interfere with flow?)
typescript and flow should be independent, although the ReactNative core is annotated for flow so those annotations probably won't work with typscript very well (although they are similar). You can definitely annotate your own files however you want, it's just that the type checking might not interoperate with core files very well.
Also note that flow is designed to be incremental, whereas it's hard to get a lot of value out of typescript without doing a full conversion of your entire project (or so I've heard).
@gabelevi: anything to add?
@Thegaram I have used react-native with Typescript by creating my own react-native.d.ts
derived from react.d.ts.
By "derived" I mean this:
declare module "react-native" {
import * as React from 'react';
import {ComponentClass, ReactType, ReactNode, ReactElement} from 'react';
export * from 'react';
...
}
There is no react-native
section under DefinitelyTyped yet and perhaps I should donate my react-native.d.ts
. The only problem is that it is very incomplete as I have been adding definitions only for the APIs and classes I needed.
UPDATE: Here is my react-native.d.ts
:
https://gist.github.com/bparadie/93cc1078d1db8fcd3c4e
@ide Why is it a big advantage to have a linter instead of a real compiler? Especially after observing that the compiler's performance seems to be better than the linter's. I am not trying to pick up a bar fight here. But last time I checked flow requires you to annotate your code at module boundaries.
What I don't understand is: If you have to add type information at one point anyways, why not just using a "real" language. I haven't heard of any linter that requires type annotations. Don't get me wrong, I like react-native and I don't have a big problem with the architectural choices you guys have made.
But looking at your dev tool chain I am seeing a flow
linter that checks the code before babel
polyfills your ES6 JS to "regular" JS. The babel step is in my opinion a cross-compilation step without type checking. What doesn't make sense to me is using two separate tools (flow and babel) that should be handled by one cross-compiler. That's why I recommend using Typescript and disabling flow for react-native development.
@Thegaram Wanted to add that you should file a "definition request" issue at DefinitelyTyped.
But you've already done that:
https://github.com/borisyankov/DefinitelyTyped/issues/5634
@bparadie I was working on a similar solution, but yours is much more detailed, thanks for sharing!
@Thegaram You are welcome! I am sure you already know that Typescript 1.6 beta has been released with support for react/JSX. I came up with my own solution for translating JSX that I can now hopefully retire. TSC 1.6 will make using react and react-native so much easier!
One aspect that this thread about flow/babel vs typescript has not covered yet is the IDE. I personally like Visual Studio Code better than Facebook's Nuclide. But I have to admit that I haven't played with Nuclide much. You could probably even mix and match (using Nuclide for TS and Code for flow/babel). Just wanted to throw this into the mix of things to consider when picking flow/babel or typescript...
Flow and babel were developed independently around the same time so
couldn't depend on each other. There are discussions about how to converge
them. It would be great to have a single system there, which would also
open up a ton of sweet cross-boundary/whole program optimizations we could
make, like automatic dead code elimination and inlining.
On Sep 6, 2015 11:18 AM, "Bernd Paradies" [email protected] wrote:
@Thegaram https://github.com/Thegaram You are welcome! I am sure you
already know that Typescript 1.6 beta has been released with support for
react/JSX
http://blogs.msdn.com/b/typescript/archive/2015/09/02/announcing-typescript-1-6-beta-react-jsx-better-error-checking-and-more.aspx.
I came up with my own solution for translating JSX that I can now hopefully
retire. TSC 1.6 will make using react and react-native so much easier!One aspect that this thread about flow/babel vs typescript has not covered
yet is the IDE. I personally like Visual Studio Code
https://code.visualstudio.com/ better than Facebook's Nuclide
http://nuclide.io/. But I have to admit that I haven't played with
Nuclide much. You could probably even mix and match (using Nuclide for TS
and Code for flow/babel). Just wanted to throw this into the mix of things
to consider when picking flow/babel or typescript...โ
Reply to this email directly or view it on GitHub
https://github.com/facebook/react-native/issues/2502#issuecomment-138105513
.
(Note the creators of Babel and Flow now work on the same Facebook JS Infra
team now, so it's even easier for them to collaborate.)
On Sep 6, 2015 7:38 PM, "Spencer Ahrens" spencer.[email protected] wrote:
Flow and babel were developed independently around the same time so
couldn't depend on each other. There are discussions about how to converge
them. It would be great to have a single system there, which would also
open up a ton of sweet cross-boundary/whole program optimizations we could
make, like automatic dead code elimination and inlining.
On Sep 6, 2015 11:18 AM, "Bernd Paradies" [email protected]
wrote:@Thegaram https://github.com/Thegaram You are welcome! I am sure you
already know that Typescript 1.6 beta has been released with support for
react/JSX
http://blogs.msdn.com/b/typescript/archive/2015/09/02/announcing-typescript-1-6-beta-react-jsx-better-error-checking-and-more.aspx.
I came up with my own solution for translating JSX that I can now hopefully
retire. TSC 1.6 will make using react and react-native so much easier!One aspect that this thread about flow/babel vs typescript has not
covered yet is the IDE. I personally like Visual Studio Code
https://code.visualstudio.com/ better than Facebook's Nuclide
http://nuclide.io/. But I have to admit that I haven't played with
Nuclide much. You could probably even mix and match (using Nuclide for TS
and Code for flow/babel). Just wanted to throw this into the mix of things
to consider when picking flow/babel or typescript...โ
Reply to this email directly or view it on GitHub
https://github.com/facebook/react-native/issues/2502#issuecomment-138105513
.
@sahrens Thanks for clarifying. One combined flow/babel tool would be cool!
Also note that flow is designed to be incremental, whereas it's hard to get a lot of
value out of typescript without doing a full conversion of your entire project (or so I've heard).
My experience has been pretty smooth with small projects but there does appear to be agreement upstream that the experience could be better and Flow's approach is influencing that - https://github.com/Microsoft/TypeScript/issues/4094
One really valuable thing that TypeScript has is a large library of typings for existing third-party libraries, DefinitelyTyped. AIUI there isn't an equivalent for Flow at the moment. It would be really helpful if Flow / TS could converge in the places where the syntax currently differs so that Flow could leverage these, and vice versa.
By the way, TypeScript is far better than Flow in my case, since the other developer I'm working with uses Windows exclusively, and TypeScript has better ES6 support. I would love TypeScript support.
+1 for official typescript support as well.
+1 for official typescript support! Would love to see this support.
+1 for official typescript support. It would be great!
+1 for official typescript support
Is this perhaps the elephant in the room?: Why not rewriting react and react-native in Typescript?
Not exactly. It's just Flow on Windows is still a work in progress, and
TypeScript is just a little more featureful. And since Facebook uses Flow a
little more than TypeScript, that slows the addition a little more. (For
similar reasons, the Facebook devs don't exactly have a huge reason to push
for good Windows and Linux ports for this, since their React Native team
exclusively uses OSX.
On Fri, Nov 6, 2015, 16:41 Bernd Paradies [email protected] wrote:
Is this perhaps the elephant in the room?: Why not rewriting react and
react-native in Typescript?โ
Reply to this email directly or view it on GitHub
https://github.com/facebook/react-native/issues/2502#issuecomment-154549882
.
I have created a pull request on DefnitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/6651
These definitions are based on @bparadie initial work and probably needs refinement. Help welcome
@bgrieder @bparadie Thanks. Were those definitions written by hand or generated from the Flow types?
If the TypeScript definitions could be generated from the Flow types that would make future maintenance easier. Of course, better yet would be to find a way to make the Flow types syntactically compatible with TypeScript.
@robertknight by hand (and there is still a lot todo)
If you find a way of generating them from the Flow types, that would be great. Do you know where to find these ?
Hey, guys!
Can you tell please how configure project for use typescript with react-native?
@tenorok I have started a project to convert the react-native UI Explorer from js to ts: https://github.com/bgrieder/RNTSExplorer. You can use that as an example
@bgrieder thank you for answer!
A tried to start your project:
npm i
grunt dev
open ios/RNTSExplorer.xcodeproj
But I have "Build failed" in XCode :-(
@tenorok Sorry you cannot get it running. Works fine on IOS 9.1 here. Can you open an issue with the list of Errors on the project itself. I will try to look at it
@bgrieder sorry, but I removed this project and already use NativeScript, which supports TypeScript from the box.
+1 for typescript support.
i _love_ resurrecting old issues. Any updates on this?
@sethx I published definitions (with contributions from others) on DefinitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/react-native
Can you elaborate on the tooling chain for supporting TS is implemented?
Did you have to modify the packer? Some info is appreciated.
On Wed, Mar 9, 2016 at 1:51 PM Bruno Grieder [email protected]
wrote:
@sethx https://github.com/sethx I published definitions (with
contributions from others) on DefinitelyTyped:
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/react-nativeโ
Reply to this email directly or view it on GitHub
https://github.com/facebook/react-native/issues/2502#issuecomment-194281907
.
@sethx Please check https://github.com/bgrieder/RNTSExplorer
I have not updated it with the latest definition files and typescript version, but it should get you started.
@bgrieder It seems the latest TS definition only works for RN 0.19? I wonder if there is more update one, if not, I would love to help with that.
@andyshuxin React-native is moving very fast - at least too fast for me to keep up with the definition files. A few people have been adding quite a lot lately and some feature beyond 0.19 are now "supported". The best way to help with this is to use it and if a recent feature is missing for you, just open a pull request against the Definitely Typed repo.
@andyshuxin I recently submitted an update that brought the type definitions up to 0.19. It wasn't that hard. I'd be willing to share some of the work. Perhaps if we can form a group of volunteers we could keep the definitions somewhat up to date.
@PublicParadise Great idea. Let's move on to #Typescript channel on Reactiflux? cc @bgrieder
@bgrieder @PublicParadise Just a heads-up: I've updated the definition to RN 0.25, currently on a forked repo at https://github.com/strikingly/definitelytyped
I haven't got the time to write tests and that's why I haven't filed the PR. But feel free to take a look or try it!
@andyshuxin I did a rough diff locally and at the first glance I'd say your changes look good.
I like that you replaced a lot of generic types with specific union types, i.e.
instead of:
mode?: string
the declaration uses:
mode?: "date" | "time" | "datetime"
That's an improvement.
One tiny thing: The first line should reflect the react-native version you are referring to.
It currently reads:
// Type definitions for react-native 0.19
Another thing @bgrieder might want to double check:
declare namespace __React {
becomes:
declare module "react-native" {
in @andyshuxin's version.
Is that ok?
What was the reason for using __React
in the first place?
There are a few places where I'd love to see more comments, i.e. minimumTrackImage
in SliderIOSProperties
.
/**
* Initial minimum value of the slider. Default value is 0.
*/
minimumValue?: number
minimumTrackImage?: any
What @bgrieder has done really nicely is that he copied the comments from the JS implementation into the declaration. It would be nice if you did the same, i.e.:
/**
* Initial minimum value of the slider. Default value is 0.
*/
minimumValue?: number
/**
* Assigns a minimum track image. Only static images are supported. The
* rightmost pixel of the image will be stretched to fill the track.
*/
minimumTrackImage?: any
In this case I grabbed the comment from SliderIOSProperties.js
.
Here is the list of properties / methods that could need comments:
ListViewProperties.enableEmptySections
MapViewPropertiesIOS.followUserLocation
MapViewPropertiesIOS.overlays
MapViewPropertiesIOS.showsCompass
TouchableWithoutFeedbackProperties.disabled
TouchableWithoutFeedbackProperties.hitSlop
TouchableWithoutFeedbackProperties.pressRetentionOffset
TouchableOpacityStatic.setOpacityTo
PixelRatioStatic.*
InteractionManagerStatic.*
ScrollViewPropertiesIOS.indicatorStyle
ScrollViewPropertiesIOS.onRefreshStart
ScrollViewProperties.refreshControl
ScrollViewStatic.*
AppStateStatic.*
BackAndroidStatic.*
NetInfoStatic.isConnectionExpensive
PushNotificationIOSStatic.abandonPermissions
...
One easy way for extracting comments is using this bash command:
# replace minimumTrackImage with $1 in a script etc...
find ./node_modules/react-native/Libraries -name '*.js' -exec grep -w -B 5 minimumTrackImage {} \;
That would give you this output without a lot of pain:
/**
* Assigns a minimum track image. Only static images are supported. The
* rightmost pixel of the image will be stretched to fill the track.
*/
minimumTrackImage: Image.propTypes.source,
So the next steps in my opinion are:
react-native.d.ts
DefinitelyTyped
Either way, great work!
Thanks for investing the time.
Let me know if you have more.
Quick follow up...
I am getting these errors when I try to use your version:
488 flatten<T extends string | null>(style: T): T
~~~~
typings/react-native/react-native.d.ts(488,36): error TS1110: Type expected.
488 flatten<T extends string | null>(style: T): T
~
typings/react-native/react-native.d.ts(488,47): error TS1005: ')' expected.
488 flatten<T extends string | null>(style: T): T
~
typings/react-native/react-native.d.ts(488,50): error TS1005: ';' expected.
488 flatten<T extends string | null>(style: T): T
~
typings/react-native/react-native.d.ts(488,51): error TS1128: Declaration or statement expected.
3652 getInitialURL(): Promise<string | null>
~~~~
typings/react-native/react-native.d.ts(3652,43): error TS1110: Type expected.
3653 }
~
typings/react-native/react-native.d.ts(3653,5): error TS1109: Expression expected.
3660 popInitialURL(): string | null
~~~~
typings/react-native/react-native.d.ts(3660,35): error TS1110: Type expected.
4587 }
~
typings/react-native/react-native.d.ts(4587,1): error TS1128: Declaration or statement expected.
@bgrieder: Not sure whether I am correct here...
It looks like we have to keep the old
declare namespace __React {
and then we have to move the methods from @andyshuxin's
export class Component<P, S> extends React.Component<P, S> {
to here
/**
* //FIXME: need to find documentation on which compoenent is a native (i.e. non composite component)
*/
export interface NativeComponent {
}
Right?
@bgrieder @andyshuxin: As I am trying to fix the problems in Andy's new react-native.d.ts
I am realizing that there is a price to pay for using explicit union types instead of strings.
Right now everybody is doing this:
const styles = StyleSheet.create({
background: {
flex: 1,
},
titleView: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
color: 'white',
fontSize: 22,
},
});
But with explicit union types in the new react-native.d.ts
I am getting tons of errors complaining about, i.e. alignItems
of type string
not being compatible with "flex-start" | "flex-end" | "center" | "stretch"
.
I think that tsc
is correct here.
There are two ways for fixing this:
const styles = StyleSheet.create<any>(...);
const styles = StyleSheet.create<LocalStyles>(...);
Latter being much better of course. The code with explicit interface would like this for the example above:
interface LocalStyles
{
background: React.ViewStyle;
titleView: React.ViewStyle;
title: React.TextStyle;
}
const styles = StyleSheet.create<LocalStyles>({
background: {
flex: 1,
},
titleView: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
color: 'white',
fontSize: 22,
},
});
Unfortunately typescript does not allow default generics, i.e.<T = any>
:
export interface StyleSheetStatic extends React.ComponentClass<StyleSheetProperties> {
create<T = any>( styles: T ): T;
}
Now, this will annoy a lot of react-native.d.ts
users, because it forces everybody to adjust StyleSheet.create
. My instincts are telling me that we should move forward with union types and document the breaking changes. We should perhaps ask the folks, who work on the Typescript language, for advice...
@bgrieder @andyshuxin: I have a modified version of Andy's new react-native.d.ts
that works for me after adjusting my code to using explicit style interfaces (StyleSheet.create<LocalStyles>(...)
).
I've also added the Easing
interface.
Here is the gist:
https://gist.github.com/PublicParadise/8760be1828f5db2cdca7e781166cab95
Comments are still missing, though...
@PublicParadise @andyshuxin
First, thank you for you work trying to bring it up to the latest version.
__React
namespace: React can be loaded in the browser using a simple <script>
tag. In which case components fall under the __React
namespace. You should try to keep this and not restrict the definition to an external module.StyleSheet.create( { ... } as LocalStyle)
It is a minor annoyance compared to the guarantee of using a correct value
Again. Great work. Thanks
IIRC string | null
is not a valid TypeScript type. Also, that distinction will be irrelevant until at least the next TypeScript release, I believe, and what would be string | null
would just become ?string
.
@bgrieder @PublicParadise Thanks for your reviews! I'm on vacation so I'll properly respond to your comments late this week. Just a quick note: the __REACT
change is in DT from which I just pulled, see https://github.com/DefinitelyTyped/DefinitelyTyped/commit/42e2274e9b5dc51598e2a7371c25a46bc31620b9
@PublicParadise Thanks for the fixes. I hope you don't mind that I've incorporated your changes into my temp repo. I also added comments to the properties and methods. I got some rather urgent matters this week, which means I may need to work on testing part some time next week. cc @bgrieder
@isiahmeadows You're right โ string | null
is illegal. Unfortunately my editor didn't choke on it.
+1 for typescript support//integration
+1 for typescript support//integration
+1 for typescript support / integration
+1 for typescript support / integration
+1 for typescript support//integration
+1 for typescript support//integration
+1 for typescript support//integration
+1 for typescript support//integration
Please consider clicking the ๐ badge on the issue rather than commenting to indicate your support
@andyshuxin type : string | null
is valid in typescript@latest (as it's coming in v.2.0) Would be nice to have those commented out ready for v.2 which has nullable types.
Giving a talk on react and typescript and contrasting with ts in angular 2 soon as demand for ts is going through the roof right now. Would love to hear if there is finally a best practice for using ts with RN in 2017?
@QuantumInformation I think it is the best approach today:
http://www.reactnative.tools/tutorials/2016/09/20/reactnative-ts/
@panarasi
nice thx
Most helpful comment
Please consider clicking the ๐ badge on the issue rather than commenting to indicate your support