Releases: rrdelaney/ReasonablyTyped
v0.13: Reason 3
This whole release was done by @cristianoc in #46!
Reason 3 Compilation
Output should now be in Reason 3 syntax 😄 Check out how awesome this output is!
type thing('x) = {. "lst": array('x)};
module Adder = {
type t('x) = {. "add": [@bs.meth] ('x => 'x)};
[@bs.new] [@bs.module "generics"] external make : 'x => t('x) = "Adder";
};
type subOpts('m, 'n) = {. "m": 'm, "n": Adder.t('n)};
The old syntax won't be supported past this point.
Optional Object Properties
See more in #46
v0.12: React Components & Imports
React components are here!
Super short example, but this works now 😄
import type { Component } from 'react'
declare module 'react-component' {
declare type props = { input?: string, b?: boolean }
declare export class ReactComponent extends Component<props> {}
}
gets compiled to
type props = {. "input": Js.Nullable.t(string), "b": Js.Nullable.t(Js.boolean)};
module ReactComponent = {
[@bs.module "react-component"] external reactcomponent_reactComponent : ReasonReact.reactClass =
"ReactComponent";
let make = (~input=?, ~b=?, children) => {
let props: props = {
"input": Js.Nullable.from_opt(input),
"b": Js.Nullable.bind(Js.Nullable.from_opt(b), [@bs] ((x) => Js.Boolean.to_js_boolean(x)))
};
ReasonReact.wrapJsForReason(~reactClass=reactcomponent_reactComponent, ~props, children)
};
};
Imports
Local imports should work exactly how you expect them to 🙂 Absolute imports will get namespaces with the capital module name
v0.11.0: Better Unions
Simpler & Inlined Union Types
It's pretty common in JS to use the following pattern:
declare function add(a: string | number, b: string | number): string
Before this release we would generate a helper type for the union, which was eliminated at runtime. Since then BuckleScript released @bs.unwrap
, allowing us to produce the following output:
external add :
a::[ | `String string | `Number float] [@bs.unwrap] =>
b::[ | `String string | `Number float] [@bs.unwrap] =>
string =
"" [@@bs.module "module"];
And the callsite comes pretty naturally! It looks like:
let result = add (`String "hello") (`Number 3.);
Unions of string literals also get processed as @bs.string
now, making them typesafe (tm):
declare function apply(input: 'add' | 'subtract'): number
external apply :
input::([`add | `subtract] [@bs.string]) =>
float =
"" [@@bs.module "module"];
Union declarations will also get inlined too!
With the input:
declare module 'module' {
declare type input = number | string
declare function apply(input: input): number
}
You'll get something like:
external apply :
input::([`Number float | `String string] [@bs.unwrap]) =>
float =
"" [@@bs.module "module"];
This should make the API's for a lot more JS libraries easier to use and closer to what JS users would expect.
Changes
- Better printing of union types
- Objects are now output as open records #29 @bbqbaron
- Class inheritance is rejected @bbqbaron
- Date type support #33 @SllyQ
- CI system
- Test suite against DefinitelyTyped #22 @fstoerkle
- Pretter pre-commit hook #24 @fstoerkle
0.10: Generics, modules, and promises
This is a pretty big release for ReasonablyTyped, it marks a huge step towards converting many FlowTyped libraries and our first external contributor! Here's what we built in the past few weeks:
Generics
ReasonablyTyped can now compile classes, interfaces and types that have type parameters!
For example, consider the following class:
declare class Test<M> {
constructor<T>(init: T): Test<T>,
add<N>(value: N): M
}
ReasonabyTyped can now turn that into:
module Test = {
type t 'm = Js.t {. add: 'n . ('n => 'm ) [@bs.meth]};
external make : 't => t 't = "Test" [@@bs.new] [@@bs.module "generics"];
};
Also note the new code generation for classes! We use the convention on creating a module with a
type named t
and export a function called make
to create that type.
Multiple modules
It can be common to see a Flow definition like:
declare module "multiple-modules" {
declare export function someTopLevel(): void
}
declare module 'multiple-modules/first' {
declare export function first(): number
declare export function second(): void
}
declare module 'multiple-modules/second' {
declare export function second(): string
declare export function third(): void
}
declare module 'multiple-modules/third' {
declare export function third(): string
declare export function fourth(): void
}
declare module 'multiple-modules/third/inner' {
declare export function third(): string
declare export function fourth(): void
}
which declares modules for it's nested files and directories in the same definition,
but still all for the same package. We now take care of these in a smart way and recognize
that they're submodules. The above would produce:
external someTopLevel : unit => unit = "" [@@bs.module "multiple-modules"];
module First = {
external first : unit => float = "" [@@bs.module "multiple-modules/first"];
external second : unit => unit = "" [@@bs.module "multiple-modules/first"];
};
module Second = {
external second : unit => string = "" [@@bs.module "multiple-modules/second"];
external third : unit => unit = "" [@@bs.module "multiple-modules/second"];
};
module Third = {
external third : unit => string = "" [@@bs.module "multiple-modules/third"];
external fourth : unit => unit = "" [@@bs.module "multiple-modules/third"];
};
module ThirdInner = {
external third : unit => string = "" [@@bs.module "multiple-modules/third/inner"];
external fourth : unit => unit = "" [@@bs.module "multiple-modules/third/inner"];
};
Shoutout to @bbqbaron for the huge contribution here!
Changlog
0.9: TypeScript and jbuilder
TypeScript
TypeScript support is here! Pass any file to ReasonablyTyped with the extension .d.ts
and the TypeScript compilation mode will be used! Note that TypeScript support is still in it's early stages, and might now always produce output. With that said, here's an example!
declare module 'numbers' {
export var xfg: number
export function add(
a: number,
b: number
): number
}
compiles to
external xfg : float = "" [@@bs.module "numbers"];
external add : a::float => b::float => float = "" [@@bs.module "numbers"];
ReasonablyTyped also supports modules with names determined by their filename, as is often seen in DefinitelyTyped.
jbuilder
Previously there was a build system in place that depended on Make and rebuild command manually to compile. This system was non-standard and didn't manage libraries or anything like that for you. Now we're using ReasonNativeProject as the basis for our build, sprinkled in with some JSOO goodness.
v0.8.0
Changes
Array<$type>
is now processed as an array- New union type generation
- Call properties on objects (
interface { (x: number): number }
) - Typeof variable declarations (
declare var exports: typeof MyClass
)
Internal Changes
- Context now gets passed around in the AST-parser part of the pipeline
- Type detection in code-generation stage