gcanti / babel-plugin-tcomb

Babel plugin for static and runtime type checking using Flow and tcomb
MIT License
482 stars 22 forks source link

Handle flow globals more accurately #106

Open rattrayalex opened 8 years ago

rattrayalex commented 8 years ago

I have a React component with a handler function that takes an argument of type SyntheticInputEvent. Flow knows how to handle this; it appears to be a Flow global of some kind. However, because it is not imported, tcomb does not know of its existence and cannot handle it.

I tried adding this at the top of my file:

import SyntheticInputEvent from 'react/lib/SyntheticInputEvent'

and got the following runtime error:

fail.js?4036:2 Uncaught TypeError: [tcomb] Invalid value [object Object] supplied to arguments[0] (expected a SyntheticInputEvent)

This is what I see poking around in the chrome debugger:

x = Proxy {
  dispatchConfig: Object, _targetInst: ReactDOMComponent, 
  _dispatchInstances: ReactDOMComponent, 
  nativeEvent: Event, 
  type: "change"…
}, 
type = SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget)

at:

else if (!(x instanceof type)) {
    _tcomb2.default.fail(message());
  }

Perhaps babel-plugin-tcomb should translate SyntheticInputEvent to be a Proxy?

gcanti commented 8 years ago

You can handle global type with the globals option https://github.com/gcanti/babel-plugin-tcomb#globals-arrayobject

Discussion here https://github.com/gcanti/babel-plugin-tcomb/issues/56

rattrayalex commented 8 years ago

Ah, thanks for the links.

I changed the title of the issue to reflect the request, then; I guess this is really a feature request for babel-plugin-tcomb to automatically include any types defined within https://github.com/facebook/flow/blob/master/lib/.

Aliasing to any is a bit unhelpful; I personally would rather just define my types by hand, which is what I did in this case.

It's also fairly inconvenient to have to declare each type you want to allow from globals. Kind of defeats the point of globals (which, while an anti-pattern in many cases, can be very helpful in cases like @STRML 's, where you use them all the time).

I'd be interested in submitting a PR for this if you're open to it.

gcanti commented 8 years ago

automatically include any types defined within https://github.com/facebook/flow/blob/master/lib/

It would be nice, but doesn't seem easy, what's your plan?

rattrayalex commented 8 years ago

I was thinking of requiring the types from, eg, flow/lib/react, checking to see if any of them are used in a given file, and if so, importing them into the target file.

Does that sound like a sensible/workable approach to you?

gcanti commented 8 years ago

flow/lib/react is a libdef file, I'm not sure what you mean by "require the types and import them into the target file". Could you please elaborate a little more, maybe with a pratical example?

rattrayalex commented 8 years ago

Hmm, I may not be understanding the technologies at hand, I'll have to play around with it...

rattrayalex commented 8 years ago

... it's not looking like I'll be able to get to this in the short term. I'd like to leave this issue open in case others have better ideas on how to approach it, but feel free to close if you disagree.

mull commented 7 years ago

@gcanti is it possible for this plugin to also read types from the [libs] entry in .flowconfig? We keep a declarations/apiTypes file that declares all our API responses, and these are then exposed as globals (say, TWApiCompany). I noticed the plugin doesn't understand these.

gcanti commented 7 years ago

Not sure but I think flow-runtime has the feature you are requesting

/cc @phpnode

mull commented 7 years ago

Thanks for the answer. That looks like it indeed does what I want, though I like tcomb a lot more :)

rattrayalex commented 7 years ago

Off topic, but @gcanti is there a compare / contrast between flow-runtime and tcomb anywhere?

On Thu, Mar 16, 2017, 04:00 Emil Ahlbäck notifications@github.com wrote:

Thanks for the answer. That looks like it indeed does what I want, though I like tcomb a lot more :)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/gcanti/babel-plugin-tcomb/issues/106#issuecomment-287023996, or mute the thread https://github.com/notifications/unsubscribe-auth/AAq_Ltaqor9OEdc1f-fMB49uyRJ8hT6zks5rmRZBgaJpZM4J1Quw .

gcanti commented 7 years ago

@rattrayalex There are some discussions here and there

Currently there are a bunch of similar libraries I'm aware of and with different goals

phpnode commented 7 years ago

@mull - flow-runtime can do that, as @gcanti says, but it's a little awkward - you have to run flow-runtime generate ./src > ./src/typdefs.js and then include typedefs.js at the entry point to your program. This collects all the external types you're using, finds their definitions and dumps them into that file so that flow runtime can understand them.

@rattrayalex tcomb and flow-runtime are conceptually quite similar, but because tcomb predates Flow it has some incompatibilities and edge cases that can make it hard to use them together. The point of flow-runtime is to be completely compatible with flow whereas @gcanti is not aiming for that with tcomb - e.g. it doesn't support things like bounded polymorphism.

gcanti commented 7 years ago

Just a clarification: tcomb was born several years ago when static type checking was semi-non existent. Now that we have both Flow and TypeScript personally I'm just interested in IO validation i.e. validating at the edge of my system (the scoped goal of io-ts), from there on I rely only on the static type checker (...with the possible exception of refinements which sometimes still require runtime checking)

rattrayalex commented 7 years ago

Gotcha. Very interesting! Thanks guys.

FWIW I'm building a JS superset called LightScript and have been thinking about incorporating tcomb or similar. It's built to be used with Flow, though integration with the typechecker hasn't been built yet. If either of you are interested in discussing/collaborating, shoot me an email.

General intention is to make programming, especially in a functional style, more ergonomic. So syntactic constructs that make some of what you're doing more convenient could be baked in.