VoliJS / Type-R

Reactive and serializable objects with transactional changes.
MIT License
51 stars 8 forks source link

TypeScript attribute typing improvements #32

Closed gaperton closed 6 years ago

gaperton commented 6 years ago

1) Instead of .has, try something like attr( Number ).value( 5 ). 2) Investigate making it the valid decorator at every given moment of time. So, it will look like @attr( Number ).value( 5 ) instead of @attr( Number.has.value( 5 ) ).

Though this issue seems to be minor, it's, in fact, the pretty big deal when working with typescript (no other option there than to use decorator). It will provide the nicer way working with ES7 as well.

@attr( User.Collection ) x;
// or
@type( User.Collection ) x;

Need to think about names. With type, it can be used everywhere and the syntax seems to be superior.

@type( User.Collection ).value( null ) x;

// or
static attributes = {
    x : type( User.Collection ).value( null ),
}

// or
static props = {
    x : type( User ).watcher( 'onChangeX' )
}

An internal structure of ChainableAttributeSpec will look like this:

interface ChainableAttributeSpec {
    ( proto : Record, name : string ) => void // decorator
    options : AttributeOptions
    value( x ) : ChainableAttributeSpec
    ...
}
gaperton commented 6 years ago

This task seems to be an important step for TS/ES API unification. Need to make sure that @type decorator will be ad-hoc polymorphic with the different behavior for different types.

An optional Type.injectAsProp( targetProto, name ) seems to be a good choice. Then, the spec itself can be produced with Type.injectAsProp.bind( options )

gaperton commented 6 years ago

Consider an alternative approach. Extract the type from the attribute, and then

@attr.toJSON( false ).changeEvents( false ) name : Type;

Also, though it's unrelated, hide the internals of the Record and Collection members under the protected directive. Resolve any internal errors with casting values to any (or the special private interface).

gaperton commented 6 years ago

Fixed in 2.1.1