babel-plugin-tcomb
babel-plugin-tcomb copied to clipboard
Trying to understand $Reify
@gcanti Can you expand on the use case for the $Reify type? I was looking around for an example on how to use this, but couldn't find one.
The use case is runtime type introspection, that is when you want to read the informations stored in your types.
When you write this:
type Credentials = {
username: string,
password: string
};
the Credentials identifier lives in "the world of types", that is it's not accessible from your JavaScript code, so normally this raises an error:
console.log(Credentials.meta) // throws ReferenceError: Credentials is not defined
when you use this plugin though your model is compiled to something like:
import _t from 'tcomb'
const Credentials = _t.interface({
username: _t.String,
password: _t.String
})
so now the Credentials identifier lives in "the world of values" and this works as expected:
console.log(Credentials.meta) // => Object {kind: "interface", props: Object, name: "Credentials", identity: true, strict: false}
BUT if you are using Flow you can't do that, since flow would complain:
src/index.js:8
8: console.log(Credentials.meta)
^^^^^^^^^^^ Credentials. type referenced from value position
3: type Credentials = {
^^^^^^^^^^^ type Credentials
Flow doesn't like that you mix types with values. So in order to have access to runtime infos but also to please Flow there is this trick: using the $Reify type
import type { $Reify } from 'tcomb'
const ReifiedCredentials = (({}: any): $Reify<Credentials>)
// ok for Flow
console.log(ReifiedCredentials.meta) // => Object {kind: "interface", props: Object, name: "Credentials", identity: true, strict: false}