Skip to content
This repository has been archived by the owner on Feb 16, 2021. It is now read-only.

Declare assertion issue #291

Closed
Gopikrishna19 opened this issue Aug 31, 2017 · 9 comments
Closed

Declare assertion issue #291

Gopikrishna19 opened this issue Aug 31, 2017 · 9 comments

Comments

@Gopikrishna19
Copy link

Gopikrishna19 commented Aug 31, 2017

version: 3.2.1

line in question:

assert(isNil(spec.meta.name) && Object.keys(spec.prototype).length === 0, function () { return 'Invalid argument type ' + assert.stringify(spec) + ' supplied to define(type) (expected a fresh, unnamed type)'; });

So can someone please explain why this is throwing error, and how the assertion works? Why would it assert the name to be null and not to have a prototype? and then reassign the same here:

Declare.prototype = type.prototype;

My code:

import Type1 from 'somewhere';

const Type2 = t.declare('Type2');

const Children = t.struct({
    children: t.maybe(t.list(Type2), 'Types')
}, 'TypeChildren');

Type2.define(Type1.extend(Children, 'NestedType'));  // failing `isNil(name)` 
                                                     // if `NestedType` is given

Type2.prototype.toggle = function () {
  // do something
};

I am getting error from the above mentioned line, because I have a name provided. Also the error doesn't exactly explain whats wrong! it is saying "define a fresh type" .. I even tried a singleton module (before code reading) but getting the same error.

Please help.

Update: The assertion is failing if Type1 has a function defined on prototype not Type2

Type1.protoype.fn = function () {  }

// :

Type2.define(Type1.extend(Children));  // failing `length(spec.prototype) === 0` 
@gcanti
Copy link
Owner

gcanti commented Aug 31, 2017

the type given to define is a throwaway type, unnamed means

Type2.define(Type1.extend(Children));

@Gopikrishna19
Copy link
Author

@gcanti Thanks for the reply, I can live with that .. but I can't define any functions in the prototype either .. is there a way to get around that? I tried defining it before the define call but I get prototype of null error.

@gcanti
Copy link
Owner

gcanti commented Aug 31, 2017

I can't define any functions in the prototype

Can't repro

const Type1 = t.struct({
  foo: t.String
});

const Type2 = t.declare('Type2');

const Children = t.struct({
    children: t.maybe(t.list(Type2))
}, 'TypeChildren');

Type2.define(Type1.extend(Children));

Type2.prototype.getFoo = function () {
  return this.foo
};

Type2.prototype.getChildrenLength = function () {
  return (this.children || []).length
};

const x = Type2({ foo: 'bar', children: [{ foo: 'baz' }] })

console.log(x.getFoo()) // => bar
console.log(x.getChildrenLength()) // => 1

@Gopikrishna19
Copy link
Author

Gopikrishna19 commented Aug 31, 2017

I believe I made a mistake when I said defining a function on Type2 throws error. It is coming from the Type1. Just checked it myself. This is checking the defined spec to not to have any prototypes. So if you have a function on Type1's prototype, it throws the error. I apologize for the confusion.

Updated the issue.

Also @gcanti is there a specific reason for these assertions? This improves readability when throwing errors. It would read NestedType, instead of Struct{ .. .children: Types}.

@gcanti
Copy link
Owner

gcanti commented Aug 31, 2017

IIRC those assertions were added to try to prevent using non-throwaway types

@Gopikrishna19
Copy link
Author

Like what I have right now? Seems like intentional limitation. Can you consider this a bug and allow removing it? At least the second assertion?

@gcanti
Copy link
Owner

gcanti commented Aug 31, 2017

Like what I have right now?

No, you are actually providing a fresh type (Type1.extend(Children)) so what you are doing seems legit, however the assert fails which is an unnecessary limitation. I guess I'll remove the assert (any better solution)?

@Gopikrishna19
Copy link
Author

Gopikrishna19 commented Aug 31, 2017

Thanks! Removing that limitation will be helpful, unless this is needed for something else, in that case, the only solution I have right now is not to extend but duplicate the Type1 struct to the extending location and add the additional props, which will be painful to manage if Type1 is huge.

@gcanti
Copy link
Owner

gcanti commented Sep 1, 2017

Just released a patch

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

No branches or pull requests

2 participants