codemix / babel-plugin-typecheck

Static and runtime type checking for JavaScript in the form of a Babel plugin.
MIT License
886 stars 44 forks source link

Support number types #89

Closed phpnode closed 8 years ago

phpnode commented 8 years ago

add built in support for int8, uint8, int16, uint16, int32, uint32, float32 and float64 types

motiz88 commented 8 years ago

Hey @phpnode, would you mind elaborating the rationale for this feature? I had previously understood this plugin as aiming to provide essentially a runtime counterpart to Flow. It now dawns on me that this is not necessarily the case, so I think some discussion is in order.

I think that to keep the plugin useful to most users, it would be best to strictly stick to an existing JS type system's semantics (I prefer Flow but it could also be TypeScript for that matter). Such an approach would mean removing these number types (possibly into their own independent plugin).

phpnode commented 8 years ago

these types are coming to JS in the nearish future as part of the typed objects spec. Right now I'm working on something which really needs this kind of safety, so I implemented this now rather than waiting (even if typed objects itself doesn't make it as a spec, the number types part is very likely to). It should be totally harmless because if you define your own int32 etc types those will take precedence.

This plugin does aim to be a runtime counterpart with Flow, but that doesn't mean that we can't support additional features, provided they're not implemented in a way that breaks Flow. In this case, if the user also wants to use these annotations with flow, they can simply define their own type aliases:

type int8 = number; // etc
phpnode commented 8 years ago

@motiz88 I do get your point that this should possibly be optional. This is a case where saying "this thing is a number" is not enough, it's really more like a constraint. I wonder if there's a sensible way for us to offer an extension point where users can define constraints of their own, in which case this could be moved.

Maybe via options in .babelrc:

{
  "plugins": [["typecheck", {
    constraints: ["./tools/number-types"]
  }]]
}

./tools/number-types.js:

export default function numberTypeConstraints ({register, expression}) {
  register('int8', {
    check: expression(`typeof input === 'number' && !isNaN(input) && input >= -128 && input <= 127 && input === Math.floor(input)`)
  });
  // etc
}

or something similar. Although it's a bit weird having plugins for a plugin.