Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed data must carry type information #3

Open
Gozala opened this issue Aug 19, 2015 · 1 comment
Open

Typed data must carry type information #3

Gozala opened this issue Aug 19, 2015 · 1 comment

Comments

@Gozala
Copy link
Collaborator

Gozala commented Aug 19, 2015

At the moment if you define types with a following signatures:

const X = Record({x: 0}, 'X')
const Y = Record({y: 0}, 'Y')

const C = Record({ data: Union(X, Y) })

Then type union interprets data value not always as one would expected:

C({data: {x: 2}}) // => Typed.Record({data: Union(X, Y)})({ "data": X({ "x": 2 }) })
C({data: X({x: 5})}) // => Typed.Record({data: Union(X, Y)})({ "data": X({ "x": 5 }) })
C({data: Y({y: 3})}) // => Typed.Record({data: Union(X, Y)})({ "data": Y({ "y": 3 }) })

C({data: {y: 2}}) // => Typed.Record({data: Union(X, Y)})({ "data": X({ "x": 0 }) })

Most likely in last statement data field was expected to be an instance of Y instead of X, although given that {y: 2} can be read both as X and Y it was interpreted as a first type in the union X. While this is bad (see #2) it does not seem to be a common issue in my experience.

What happens far more often in my experience is that new type is defined which supposed to be added to a type union (but for whatever reasons it was not added to type union):

const Z = Record({ z: 0 })

C({data: Z({z: 5})}) // => Typed.Record({data: Union(X, Y)})({ "data": X({ "x": 0 }) })

Now surprise and a problem is far worse in this case, as passed data field had a type but it got casted to a completely different type. There is also no simple way to avoid or spot this issue.

@Gozala
Copy link
Collaborator Author

Gozala commented Aug 19, 2015

I think it would make sense to generate a type identifier field for every record type that is going to be included with each instance. That would have several benefits:

  1. Type checking will become a lot simpler

    const isTypeOf = (x, X) => X[typeID].indexOf(x[typeID]) >= 0

    This will also work for union types which is currently painful.

  2. It may enable passing typed records between web workers without loosing type information, although it is unclear if they will be at all useful given that same types won't be available in the worker context.

  3. We could use that to prevent type casting for type unions although without also doing Reconsider duck typing records #2 we would make type union fields odd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant