Comments (12)
@dcousens If you're open to PRs, I can take a first pass at this.
from typeforce.
Ok, I'm thinking through this a bit more, and I want to get your opinion before I proceed.
It seems the main use of this function is to determine whether value
is constructed of Type
. The way this is handled now is by checking whether the constructor.name
of value
is equivalent to the string type
.
There are other ways to accomplish something similar, each with their own drawbacks:
1. Checking value instanceof Type
.
Pros:
- fixes the mangling issue since we're checking the actual constructor
Cons:
- if
Type
is imported twice, this check may fail (an edge case, but difficult to debug) - if
value
is constructed of an extension ofType
, this check will fail - if
value
exhibits the properties ofType
but is not literally constructed, this check will fail
2. Checking Type.prototype.isPrototypeof(value)
Pros:
- fixes the mangling issue
- if
value
is constructed of an extension ofType
this check will work - if
value
is constructed by copying methods/properties fromType.protoype
, but is not literally constructed, this check will work (e.g.Object.create
)
Cons:
- if
Type
is imported twice, this check may fail (an edge case, but difficult to debug) - if
value
exhibits the properties ofType
but is not created, this check will fail (e.g.Object.assign
)
3. Iterating over the methods/properties of Type.prototype
to ensure equality with value
Pros:
- fixes the mangling issue
- if
value
is constructed of an extension ofType
this check will work - if
value
has copied methods/properties fromType.protoype
, but is not literally constructed, this check will work (e.g.Object.create
,Object.assign
)
Cons:
- if
Type
is imported twice, this check may fail (an edge case, but difficult to debug) - if
value
has methods/child objects that do the same thing functionally asType
, but are not literally copied, this check will fail
4. Iterating over the methods/properties of Type.prototype
to ensure type equivalence with value
Pros:
- fixes the mangling issue
- if
value
is constructed of an extension ofType
this check will work - if
value
has copied methods/properties fromType.protoype
, but is not literally constructed, this check will work (e.g.Object.create
,Object.assign
) - if
Type
is imported twice, this check will work - if
value
has methods/child objects that are of the same type but not literally copied, this check will work
Cons:
- Introduces a "false positive" possibility where
value
can "look like"Type
by having functions with the same names, but not implementing those functions the same way.
My proposal would be to do 2 with a fallback to 4. What do you think @dcousens ? Is the false positive here acceptable, or are we better off rejecting value
s that are similar but not are not constructed of Object.create
d?
Additionally, is there a desire to extend this beyond constructors? If so, it may make sense to generalize this even further to have the quacksLike
signature look like quacksLike(Foo.prototype)
, instead of quacksLike(Foo)
(both in contrast to the current signature: quacksLike('Foo')
)
from typeforce.
I can't see how to do this without a breaking change
from typeforce.
This would definitely be useful. The current implementation breaks when you mangle constructor names, e.g. with Uglify.
What are you concerned with it breaking?
from typeforce.
It is a breaking change insofar as it indiscriminately allows any type if uglify
is used.
In libraries that use this module, we recommend them to:
If you uglify the javascript, you must exclude the following variable names from being mangled: BigInteger, ECPair, Point. This is because of the function-name-duck-typing used in typeforce.
uglifyjs ... --mangle --reserved 'BigInteger,ECPair,Point'
from typeforce.
Apologies, @treygriffith I thought I was replying to #47
The breaking change here is that Users are currently passing a String
, and we are changing the API to be an instantiated object with property matching.
from typeforce.
@dcousens yeah I see that now. The way to introduce this might be through a new method (shame since the method name quacksLike
is so good!).
Thanks for the note on the ECPair
, Point
, and BigInteger
- I only found one of those myself, so will be good to preemptively add those others to the reserved
list.
from typeforce.
@treygriffith major bump is how I would do it, tbh.
from typeforce.
@treygriffith I am open to it, I just can't guarantee when it will merge.
#45 is something I'd additionally want to solve by 2.0.0
... so open to your thoughts there too.
from typeforce.
Can't respond right now, will tonight.
from typeforce.
if Type is imported twice, this check may fail (an edge case, but difficult to debug)
This issue is why quacksLike
was introduced the way it is.
Introduces a "false positive" possibility where value can "look like" Type by having functions with the same names, but not implementing those functions the same way.
I think this is a great solution personally. It is by definition a great way to enforce quacksLike
, better than focusing on the data too.
We could make it a score based system. 90% alike etc...
from typeforce.
I kind of figured that might be the case. I'll re-work the PR to do a type equivalence check on all the properties.
from typeforce.
Related Issues (20)
- Standard failing HOT 3
- maybe/oneOf JSON when used with complex types outputs [object Object]
- Avoid recursive throwing / return Error HOT 5
- propertyKeyType for `typeforce.map` HOT 1
- typeforce 1.5.1 breaks bitcoinjs-lib 1.5.8 HOT 25
- Document quacksLike / tuple / map? HOT 4
- strict in quacksLike? HOT 2
- breaks when uglified with mangle:true HOT 12
- Add uglfiyjs mangling warning to README HOT 1
- isFiniteNumber? HOT 2
- split on multiple files HOT 2
- Tuple w/ strict should enforce maximum length HOT 1
- `.Object` and `.object` are too similar HOT 3
- Remove typeforce.object in favour of typeforce.compile
- Optional error information HOT 4
- Add exception capturing tests for arrayOf, map, object and tuple
- Error.captureStackTrace is undefined HOT 3
- anyOf should accept `Array` argument, not `arguments`
- Tests failing in Node <LTS
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typeforce.