Giter Site home page Giter Site logo

rescript-association / gentype Goto Github PK

View Code? Open in Web Editor NEW
760.0 14.0 44.0 43.65 MB

Auto generation of idiomatic bindings between Reason and JavaScript: either vanilla or typed with TypeScript/FlowType.

Home Page: https://rescript-lang.org/docs/gentype/latest/introduction

License: MIT License

OCaml 99.47% Dockerfile 0.01% Shell 0.03% JavaScript 0.41% Nix 0.09%
types javascript reasonml flowtype bucklescript type-safety typescript

gentype's People

Contributors

0xflotus avatar benadamstyles avatar bobzhang avatar btmills avatar cometkim avatar coobaha avatar cristianoc avatar dependabot[bot] avatar evxn avatar haroenv avatar idkjs avatar jchavarri avatar mrtnzlml avatar nhducit avatar nikgraf avatar nirvdrum avatar quinn-dougherty avatar rickyvetter avatar ryyppy avatar sync avatar wokalski avatar xtian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gentype's Issues

Declaring genFlow as dependency in package.json

Thanks for creating this tool, this might be a game changer in multiple cases for Reason adoption ✨

I've been trying to set up a project that uses genFlow, and added to package.json:

  "devDependencies": {
    "bs-platform": "^4.0.3",
    "genFlow": "cristianoc/genFlow"
  }

I'm getting an error from esy though:

info esy install 0.2.4
info checking https://github.com/ocaml/opam-repository for updates...
info checking https://github.com/esy-ocaml/esy-opam-override for updates...
esyi: no checksum provided for @opam/ppx_tools@opam:0.1  
        resolving metadata @opam/ppx_tools@opam:0.1
        processing
      /Users/javi/.esy/esyi/opam-repository/packages/ppx_tools/ppx_tools.0.1
      opam package
esy: error, exiting...
     error running command:
     '/Users/javi/.nvm/versions/node/v8.11.1/lib/node_modules/esy/_build/default/esyi/bin/esyi.exe'

Is it possible to define genFlow as a native dependency?

Add support for record types and conversions.

A record type such as this

type r = {x:int, y:option(int)}

is exported to Flow/Typescript as

export type r = {x:number, y?:number}

Since Reason's internal representation of records uses arrays, a conversion between the representations is performed. The direction of the conversion is determined by whether the record appears in a positive position in the type of the value annotated with @genFlow. (For example, the return type of a function is a positive occurrence, but a direct argument is a negative occurrence).

Implemented in

Add support for interface files.

When an interface Filename.rei is present, process Filename.cmti instead of Filename.cmt. This allows exporting the details of types presented by the interface, not the implementation.

Any annotations in Filename.re are ignored if Filename.rei is present, as the interface is the source of truth.

Generate bindings in windows

After puting binary in correct path and adding path to bs-compiler and runing build generated bindings has incorrect path(node can't recognize it)

/* Untyped file generated by genType. */

const Curry = require('bs-platform/lib/js/curry.js');

const ReCounterBS = require('.\ReCounter.bs'); <---- THIS IS NOT CORRECT

i manualy changed it to

const ReCounterBS = require('./ReCounter.bs');

and it start working

Emit PropTypes code for "untyped" language

I just realized it would be really great if we could emit actual PropTypes code, as stated in the React documentation.

Since interoping with ReasonReact components in JavaScript land doesn't have any static type checking, it would be great to have at least accurate runtime warnings.

Although this would force the user to use the PropTypes package, I think it's a nice enforcement for good practise.

Create a `tutorials` / `docs` project

Create a project based on my Reason optimized antwar-default setup.

Following topics should be covered:

  • Practical scenarios you might want to use genType for
  • All kinds of genType features / annotations
  • Simple integration examples with common tools (like mdx)
  • See #70 for more ideas

This project should also be hooked up to the test setup to prevent regressions as well.

Bake version information in binary

Currently gentype.native --version doesn't yield any information.

Expected:

./gentype.native --version
0.15.0

This would be very helpful for release management later on, when we release on npm.
I need to do some research how to do this "search & replace" work before compilation with bsb-native.

One idea would be to factor out a Version module as a CPPO file and preprocess it with the current package.json version.

https://github.com/mjambon/cppo

Rename to genType

Gradually rename the project to genType, with small extensions followed by one breaking change.

Support conversion for user-defined types.

This generates conversion functions for optionals:

[@genFlow]
let consumeOption = (x: option(int)) =>
  Belt.Option.(x->(mapWithDefault(0, n => n)));

But this does not, and treats the user-defined optionInt as a completely opaque type:

[@genFlow]
type optionInt = option(int);

[@genFlow]
let consumeOption2 = (x: optionInt) =>
  Belt.Option.(x->(mapWithDefault(0, n => n)));

Is there a roadmap for a potential integration upstream with BuckleScript?

Thanks for genFlow!!! It's really amazing ✨

I am wondering if there are any plans for an integration of genFlow / genType upstream with BuckleScript? That would simplify most of the setup / configuration, as it could become just another bsconfig.json option. cc @bobzhang

I have also noticed that re.js files are not updated after compiling, and genFlow users are forced to call bsb -clean-world and then bsb -make-world again, or clean the .re.js files in some other way before re-compiling. Not sure if this is something that could also go away if genFlow was integrated with BuckleScript?

In case there is a list of features or additions that need to happen before this potential integration, how would that list look like? Maybe making it public would enable more people to jump onboard and help with the project :)

Thanks again for all your great work!!

Produce JS object types with property names that correspond to reserved words in Reason

Currently it's not possible to do something like:

[@genFlow]
type action = {
  type: string,
};

Because type is reserved in Reason.

I was wondering if there could be some kind of mechanism to produce the following type in JS:

export type action = {|type:string|};

even if in Reason we use some derivation of it that gets mangled during the process.

BuckleScript had a name mangling mechanism that converted type__ (two underscores) into type. It can still be seen with [@bs.deriving jsConverter] (example). I think the part of BuckleScript that does it is this lam_methname.ml.

Or maybe using something similar like [@bs.as "type"] like bs.abstract?

Unexpected type annotations in generated `untyped` code

Setup

genflowconfig.json:

{
  "language": "untyped",
  "shims": []
}

With following Reason file src/mycomponent.re....

[@genFlow]
let make = (children) => {
  ...component,
  render: _self => {

    <> <Meta siteName="Reason Association" title description keywords /> children </>; */

    <div>("Test" |> ReasonReact.string)</div>
  },
};

... genFlow emits following code (mycomponent.re.js):

/* Untyped file generated by genFlow. */

const ReasonReact = require("reason-react/src/ReasonReact.js");
const layoutBS = require("./layout.bs");

export const layout = ReasonReact.wrapReasonForJs(
  layoutBS.component,
  (function _(jsProps: Props) {
     return layoutBS.make(jsProps.children);
  }));

Expected output

/* Untyped file generated by genFlow. */

const ReasonReact = require("reason-react/src/ReasonReact.js");
const layoutBS = require("./layout.bs");

export const layout = ReasonReact.wrapReasonForJs(
  layoutBS.component,
  (function _(jsProps) {
     return layoutBS.make(jsProps.children);
  }));

Note that the output doesn't contain any Props annotation in the callback function argument of wrapReasonForJS.

No currying in ReasonReact runtime

When genType encounters a React component it generates a conversion wrapper that calls make directly. It doesn't use currying, so the generated output can be unsafe if BuckleScript doesn't optimize the make call to be an uncurried JS function.

Example:

let component = ReasonReact.statelessComponent("Component");

[@genType]
let make = (~count) => {
  Js.log(count);
  _children => {
    ...component,
    render: _ =>
      ReasonReact.string("Component that needs curried call" ++ string_of_int(count)),
  };
};
function make$1(count) {
  console.log(count);
  return (function () {
      return /* record */[
              /* ... React component internals here ... */
            ];
    });
}
export type Props = {|count: number, children?: mixed|};

const component: React$ComponentType<Props> = ReasonReact.wrapReasonForJs(
  MyFileBS.component,
  (function _(jsProps: Props) {
     /* problematic call here: */
     return MyFileBS.make(jsProps.count, jsProps.children);
  }));;
exports.component = component

Support polymorphic props.

A component type is currently exported as:

export const component: React$ComponentType<Props> = ...

In order to add polymorphic props, one would need to add type parameters. However, this can only be done for a function type, so the result would be for example:

export const component: () => <T1> React$ComponentType<Props<T1>> = ...

This would introduce the complication that component becomes a function that needs to be called from the JS side.
In addition, it is not mandatory to pass the type parameters when calling the function from JS. And if no type parameter is specified, it's equivalent to passing any.

It seems simpler to just treat polymorphic props as any in the first place.

[Design] Allow renaming of exported component props.

Renaming in type definitions is already supported with @genType.as, for example:

[@genType]
type t  = { [@genType.as "type"] type_: string, number:int };

One would like to do the same when exporting components:

[@genType]
let make = (~type_, ~number, _children) => {
...

however it's not possible to add annotations next to named arguments above.

make function doesn't translate JS object -> record correctly

Input:

[@genFlow]
type person = {
    firstname: string
};

[@genFlow]
let make = (~person:person, _children) => {
    ...component,
    render: _ => {
       let {firstname} = person;

       <div style>
         ({j|Hi $firstname|j} |> ReasonReact.string)
       </div>
    }
}

Output:

export const SomeComponent: React.ComponentClass<Props> = ReasonReact.wrapReasonForJs(
  SomeComponentBS.component,
  (function _(jsProps: Props) {
     return SomeComponentBS.make(jsProps.message, jsProps.color, {firstname:jsProps.person[0]}, jsProps.children);
  }));

Note the {firstname:jsProps.person[0]} argument, which is a Js.t({."firstname": string}) type in Reason land.

Expected:

export const SomeComponent: React.ComponentClass<Props> = ReasonReact.wrapReasonForJs(
  SomeComponentBS.component,
  (function _(jsProps: Props) {
    console.log(jsProps); 
     return SomeComponentBS.make(jsProps.message, jsProps.color, [jsProps.person.firstname], jsProps.children);
  }));

Note the [jsProps.person.firstname] in the make function call, which afaik would be the right internal representation of an OCaml record.

0.14.0 tar link is incorect

root cause: 0.14.0 is released under a name without v, 0.14.0 instead of v0.14.0

download link in ReadMe:

https://github.com/cristianoc/genType/releases/download/v0.14.0/gentype-linux.tar.gz

correct link.

https://github.com/cristianoc/genType/releases/download/0.14.0/gentype-linux.tar.gz

Treat optional(_) fields of object types as with records (no conversion JS <-> Reason).

This type is a JS object type with a field c of Reason's option type:

[@genType]
type mix = {
  .
  "a": int,
  "b": int,
  "c":
    option({
      .
      "name": string,
      "surname": string,
    }),
};

It can be converted to a JS representation like this:

type mix = {|a:number, b:number, c?:{|name:string, surname:string|}|};

The conversion function can simply be the identity, to allow direct interop without any copying, all while using idiomatic options on the Reason side.

The constraint is on the JS type checking: the type for c ensures that it can not be null, just undefined.

Support for tuples

I've observed that tuples are not yet supported. Tuples are implemented as arrays in all Flow, TypeScript and BuckleScript so it seems something that could be done without going through many loops...

Is there anything from a type system perspective that is preventing this feature?

If there are no blockers and it's not something that is being worked on at the moment, I would like to take a stab to get more familiar with genType code 😄

Reason-React example fails to compile if run through refmt.

Within the reason-react-example, code fails compilation when passed through refmt.

Steps to repro

  1. Open up project in VS code with reason-language-server extension and format on save enabled
  2. Open Greeting.re
  3. Start the project in terminal with yarn start
  4. Save Greeting.re
  5. Observe syntax changes and the following error from the terminal
1/2] Building src/interop/Greeting.mlast
File "/Users/marcel/projects/lab/genType/examples/reason-react-example/src/interop/Greeting.re", line 40, characters 32-39:
Error: Syntax error: Labels are not allowed inside a tuple not expected.

  We've found a bug for you!
  /Users/marcel/projects/lab/genType/examples/reason-react-example/src/interop/Greeting.re

  There's been an error running Reason's refmt parser on a file.
  This was the command:

  /Users/marcel/projects/lab/genType/examples/reason-react-example/node_modules/bs-platform/lib/refmt.exe --print binary '/Users/marcel/projects/lab/genType/examples/reason-react-example/src/interop/Greeting.re' > /var/folders/kt/_xgpkvhs5l957cd3gb_qxmsm0000gn/T/ocamlppb29e42

  Please file an issue on github.com/facebook/reason. Thanks!

ninja: error: rebuilding 'build.ninja': subcommand failed
>>>> Finish compiling(exit: 1)

Refmt made the following changes to Greeting.re

[@genType]
-let make = (~message, ~someNumber, ~extraGreeting=?, ~polymorphicProp, _children) => {
+let make =
+    (~message, ~someNumber, ~extraGreeting=?, ~polymorphicProp, _children) => {
   ...component,
   render: _self => {
     Js.log2("polymorphicProp:", polymorphicProp);
@@ -14,8 +15,8 @@ let make = (~message, ~someNumber, ~extraGreeting=?, ~polymorphicProp, _children
       | Some(g) => g
       };
     <div>
-      <MyBannerRe show=true message=(message ++ " " ++ greeting) />
-      (ReasonReact.string("someNumber:" ++ string_of_int(someNumber)))
+      <MyBannerRe show=true message={message ++ " " ++ greeting} />
+      {ReasonReact.string("someNumber:" ++ string_of_int(someNumber))}
     </div>;
   },
 };
@@ -36,7 +37,7 @@ let concat = String.concat;
 let testNamedArgs = (~a, ~b, x, ~c, ~d, y, ~e) => a + b + x + c + d + y + e;

 [@genType]
-let testCallNamedArgs = (foo: ((~a: int, ~b: int) => int), a, b) =>
+let testCallNamedArgs = (foo: (~a: int, ~b: int) => int, a, b) =>
   foo(~a, ~b);

Disabling refmt on save prevents this, but is not ideal.

Run `build:examples` for CI test (for now)

We currently don't do any regression tests, so for now it would be great to do the following:

Add a test npm script which does:

  • npm run example:build
  • Do a git command which checks if any checked in files have changed. If there are diffs, the test should fail and stop the CI process

API design and language cleanup.

Trying to consolidate some common themes emerging in received feedback, and to define the language to talk about them. The goal here is to have a cleanup pass on outstanding questions, API design, and documentation.

Terms

Type and Value.

Import and Export something.

Modules and Classes.

Renaming when e.g. type is a keyword, or A is capitalized, or using a different name for binding is useful.

Immutable Fields of objects and records are immutable by default, and arrays are opt-in immutable by using ImmutableArray.t.

Type Expansion see below.

Principles

  1. If you’ve created some binding in one module, you should be able to use it from another module. (Instead of creating the same binding once again).
    Related: @ybybzj’s issue #63.

  2. It should be clear whether an annotation means that you’re importing or exporting something.
    Values can be either imported or exported, not both. Values already have a special syntax for export: the external keyword.
    Types can be imported, exported, but perhaps even both (e.g. import a JS type that is a string, and use it as a string in Reason, one needs to check that the two representations are consistent). The information on whether a type is imported or exported must be in the annotation.

  3. If in doubt, the default meaning of an annotation is export. But, one could have also an explicit annotation. E.g. for types, export is the default, but one could add a @genType.export annotation too, to be super clear.

  4. If an exported type is defined in terms of another type which is not annotated, what happens should be clear. Type expansion could be interesting to have, where types are expanded (i.e. inlined) until one reaches an annotated type, or a cycle. Also, should type expansion work across modules, and is that easy to implement? See also #71.

Problems and solutions

Q: How can I add annotations if I don't have, or can’t change, the code?

Example1: standard library, Belt, ReasonReact. (For now: shims).

Example2: @MarcelCutts on "exporting a type generated by GraphQL”. Or a type coming from invoking a functor.
Progress can be made on the second example by looking into Type Expansion.
Related: #64

Q: What about JS classes?

There’s not a clear answer for now.
Related: @ybybzj’s issue #63

Q: What should Modules export to, and with what representation, in the JS world?

There's an object-like quality in the values they contain, but a namespace-like quality in the types they contain.
Related: #42
Related: #41

Import type definitions from other files.

Currently, type definitions are known only for types defined in the current file.
Type definitions are needed to generate converters.
Support reading type definitions from other files.

Module has no default export

Steps to reproduce:

  • genflowconfig.language = "typescript"

Create a file SomeComponent.re:

let component = ReasonReact.statelessComponent("SomeComponent");

[@genFlow]
let make = (~name, _children) => {
    ...component,
    render: _ => {
       <div>
         ("Hi, this is " ++ name |> ReasonReact.string)
       </div>
    }
}

This will create a SomeComponent.tsx file, with following exports:

/* Typescript file generated by genFlow. */

// tslint:disable-next-line:no-var-requires
const ReasonReact = require("reason-react/src/ReasonReact.js");
// tslint:disable-next-line:no-var-requires
const SomeComponentBS = require("./SomeComponent.bs");

// tslint:disable-next-line:interface-over-type-literal
export type Props = {name:string; children?:any};
export const SomeComponent: React.ComponentClass<Props> = ReasonReact.wrapReasonForJs(
  SomeComponentBS.component,
  (function _(jsProps: Props) {
     return SomeComponentBS.make(jsProps.name, jsProps.children);
  }));

Expected:

Last line should contain:

export default SomeComponent;

Motivation

  • I want to be able to do import SomeComponent from "SomeComponent" instead of import {SomeComponent} from "SomeComponent"

Proposal for shims format

The current shims format is pretty custom and requires an extra parse step. I think it might be good to use the key-value object JSON structure instead.

Current:

[
  "Js=Js",
  "Obj=Obj",
  "ReasonReact=ReactShim",
]

Proposal:

{
  "Js": "Js",
  "Obj": "Obj",
  "ReasonReact": "ReactShim",
}

Exposing module types

I've been experimenting with mixing ReasonML and regular JS to provide a solid foundation across side effects.

One thing that I would find amazingly useful is being able to run genType on types within instantiated modules so I can expose those to regular flowd components

A reason-apollo example

[@genType]
module GetUser = [%graphql
  {| query getUser { user { firstName, lastName, telephone } }|}
];

module GetUserQuery = ReasonApollo.CreateQuery(GetUser);

[@genType]
type responseType = GetUser.t;

Here responseType ends up being

export opaque type responseType = GetUser_t;

where GetUser_t cannot be resolved.

Is this something that's on the roadmap? Or is it one of those things that is actually rather difficult?

Syntax error in Flow output

Input:

let foo = (a: option('a), b) => b(a);

Output:

export const foo: <T1,a>(?a, (?a) => T1) => T1 = function ...

Flow (v0.83) doesn't seem to be able to parse the first parenthesis in (?a). Without parens it works:

export const foo: <T1,a>(?a, ?a => T1) => T1 = function ...

Make (sub)modules `genType`able

Given following file foo.re:

/* foo.re */

module Bar = {
  let values = [1, 2, 3];
};

I want to be able to import this module in TypeScript like this:

/* test.ts */
import { Bar } from "foo.ts";

My ideal fix

/* foo.re */

[@genType]
module Bar = {
  let values = [1, 2, 3];
};

Resulting TypeScript wrapper of Bar: Js.t({."values": any})
In case any of the module's values / types are annotated as well, it will refine the types. E.g.

/* foo.re */

[@genType]
module Bar = {
 [@genType]
  let values = [1, 2, 3];
};

Resulting TypeScript wrapper of Bar: Js.t({."values": js(list(int))})

Concrete example (doing workarounds)

/* data.re */
module Organizer = {
  type t = { name: string };
  let organizers = [|
   {name: "organizer 1"},
   {name: "organizer 2"}
  |];
};

/* I need to flatten this value, so I can access it in plain JS */
let organizers = Organizer.organizers;
/* about.mdx */
import { organizers } from "./data.re";

# Organizers

Some text about our organizers.

<Organizers organizers={organizers} />

Property 'opaque' has no initializer and is not definitely assigned in the constructor.

Following on the TypeScript example to integrate Reason to a TypeScript React project, I get the following error in ReasonPervasives.shim.ts from TypeScript:

Property 'opaque' has no initializer and is not definitely assigned in the constructor.

It comes from this bit of code:

export abstract class Cons<T> {
  protected opaque: T;
}

VSCode proposes two possible fixes:

  • Add undefined type to property opaque
export abstract class Cons<T> {
  protected opaque: T | undefined;
}
  • Add definite assignment assertion to property protected opaque: T;:
export abstract class Cons<T> {
  protected opaque!: T;
}

Is one solution, or both, okay? Is one better than the other? why?

bs.js modules imported in commonjs format with "es6" config

Pretty minor, but when using "module": "es6" in bsconfig.json, the main BuckleScript file that is consumed from the .re.js files is still being imported using require:

// $FlowExpectedError: Reason checked type sufficiently
const DemoBS = require('./Demo.bs');

The expected behavior would be that these imports also comply with the module config value.

Module resolution

To generate imports, some form of module resolution is required.
The current simplifying assumption is that you only use types from modules belonging to the same directory.
For module resolution, one possibility is to look at the metadata in lib/bs/.sourcedirs.json e.g.

{ "dirs" : [ "src" , "src/nested" , "src/shims" ] , "generated" : [] }

Build proper integration test infrastructure (strategy)

My idea is to introduce some kind of snapshot testing mechanic, which runs the native binary on multiple input files and checks if the output matches the expected format.

odoc does something similar with a home brewed snapshot tester with a mechanic to automatically submit changes to the expect-file in case there are expected changes.

Record to JS object function not added when using a record with type variable

I have the following:

[@genFlow]
type basicAction = {
  actionType: string,
  payload: string,
};

[@genFlow]
let createBasicAction = (actionType, payload) => {actionType, payload};

which produces:

export type basicAction = {|actionType:string, payload:string|};
export const createBasicAction: (string, string) => basicAction = function _(Arg1, Arg2) { const result = TestBS.createBasicAction(Arg1, Arg2); return {actionType:result[0], payload:result[1]} };

Then I tried:

[@genFlow]
type action('a) = {
  actionType: string,
  payload: 'a,
};

[@genFlow]
let createAction = (actionType, payload) => {actionType, payload};

And genFlow outputs:

export type action<a> = {|actionType:string, payload:a|};
export const createAction: <T1>(string, T1) => action<T1> = TestBS.createAction;

In the first case, createBasicAction wraps the array with a JS object {actionType:result[0], payload:result[1]}.
In the last case though, createAction –that returns a generic type in Flow– doesn't include the JS object wrapping and directly returns the value from TestBS.createAction. I was expecting it to behave like createBasicAction and have the returned value wrapped.

I guess this is known, but I couldn't find this particular case in the README. I wanted to make sure I'm not doing anything wrong, is there a way to have the converting code added to functions with this kind of types?

[@genType] with None produces output that Flow can't type check

I was trying to expose Some and None to JS code. Some works great, but I found this output with None:

Input (.re):

[@genType]
let none = None;

Output (.re.js):

export const none: ?T1 = OptionBS.none;

Then Flow fails to type check in any case as there's no way to define T1. I know this case is tricky from a type perspective as there is no output info about the result. But maybe this should be reflected in the output somehow? Maybe not producing anything and showing an explanatory comment, or exposing the value as function:

const none = <T1>(a: T1): ?T1 => OptionBS.none;

to be able to fill the type param.

Need troubleshooting tips (expecting Greeting.re.js but not generated)

I followed the instructions in Readme:

  • downloaded genflow.native and installed in usr/local/bin
  • export BS_CMT_POST_PROCESS_CMD=genflow.native
  • added genflowconfig.json file
  • added ReactShim.shim.js file to source path
  • tried adding [@genType] or [@genFlow] above make function

I was confused about [@genType] or [@genFlow]. However, I tried both and neither worked.

Consider emitting `.d.ts` files as output for TypeScript

Hi! @ryyppy showcased this in ReactAlicante last weekend, and it was very cool! 😎

After the talk, we had a very interesting conversation with @ForbesLindesay where he mentioned that it will increase performance if the TypeScript output were only declaration files and not actual source code (like the case with flow).

Maybe we can consider that? This issue is just to keep track of that conversation 😉

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.