gcanti/tcomb-form

Discuss: optional `tcombFormOptions` field on `Type`

Opened this issue · 2 comments

First off, tcomb-form is awesome. Thanks!

I currently have the use case where tcomb-form uses types written solely to support form generation, i.e. the same types aren't used elsewhere (the data is otherwise managed in non-JS code). I suspect this is not an uncommon use case.

The code has quite some struct nesting, and looks like this:

const Sometype = t.struct({
    info: t.String,
    morestuff
}, "Sometype");

const Someothertype = t.struct({
    stuff
}, "Someothertype ");

// *and so on*

const options = {
   stuff
   fields: {
       someField: {
             fields: {
                 deeperNestedField: {
                      item: {
                          fields:
                              info: {
                                  help: "useful text"
                              }
                          }
                      }
                  }
             }
       }
    }
}

It's easy to lose track of things in such an options object. It would be more natural for the reader of this code if I could write

const Sometype = t.struct({
    info: t.String,
    morestuff
}, "Sometype");   

Sometype.tcombFormOptions = {
   fields: {
       info: {
           help: "Some limited info, max 30 chars";
       }
   }
};

The idea would be that tcomb-form merges the tcombFormOptions field with the correct subobject in the options prop to Form, where the latter overwrites the first. This way you can document static stuff, like help and error texts, right with the data definition, while still keeping all the dynamism that makes tcomb-form awesome.

Basically, I understand and strongly support the architectural choice of separating the tcomb types and their tcomb-form configuration, but it some cases this separation is less useful than others. Given that there's already support for getTcombFormFactory, this might be a reasonable suggestion to get the best of both worlds?

I'd be happy to code the PR if you'd like.

@gcanti i'm still pretty interested to code this up, but i strongly value your opinion. I'd like to know if this has any chance of getting merged in.

Do you think monkey patching a type that way (i.e. adding a tcombFormOptions field to an type object) is a nice approach? Does it match your design ideas behind tcomb (form)?

@eteeselink using a function seems more flexible (something like getTcombFormFactory)

Sometype.getTcombFormOptions = (options) => ({
   fields: {
       info: {
           help: "Some limited info, max 30 chars";
       }
   }
});

To show some code we can reason about, I put up a POC here