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

adding a custom type, typeMap is frozen #15

Closed
dkebler opened this issue Jan 12, 2017 · 8 comments
Closed

adding a custom type, typeMap is frozen #15

dkebler opened this issue Jan 12, 2017 · 8 comments

Comments

@dkebler
Copy link

dkebler commented Jan 12, 2017

Little help please, I'd like to do this.

mytypechecker.js

let tc = require('typechecker')

// add custom types
tc.isBuffer = function isBuffer(obj) {
  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}

// add map entries for custom types
tc.typeMap.buffer = tc.isBuffer

module.exports = tc

that might work but can't try it because the typeMap object is frozen.

Not sure why this was done (save fools from themselves?)

So how can I add my custom types to the library so I can use getTypes without having to pass it an additional map every time

i.e. don't want to do this every time.
expect(u.getType(Buffer.from('this is a test'), { buffer: u.isBuffer })).to.equal('buffer')

if typeMap needs to be frozen why bother to export it? How about not and providing a registration function to register additional custom types for use with getType?

Thx.

@balupton
Copy link
Member

balupton commented Jan 12, 2017

Modifying typeMap directly would also change functionality for other packages that use typechecker which could cause problems.

However, getType accepts a second parameter that can be a type map, so you could do the following:

// custom-typechecker.js
const typechecker = require('typechecker')
const customTypeChecker = Object.assign({}, typechecker)

const customTypeMap = {
	array: typechecker.isArray,
	boolean: typechecker.isBoolean,
	date: typechecker.isDate,
	error: typechecker.isError,
	class: typechecker.isClass,
	function: typechecker.isFunction,
	null: typechecker.isNull,
	number: typechecker.isNumber,
	regexp: typechecker.isRegExp,
	string: typechecker.isString,
	'undefined': typechecker.isUndefined,
	buffer: Buffer.isBuffer,  // must be before isObject, as otherwise isObject will catch it
	map: typechecker.isMap,
	weakmap: typechecker.isWeakMap,
	object: typechecker.isObject
}

customTypeChecker.getType = function customGetType (value, _typeMap) {
	return typechecker.getType(value, _typeMap || customTypeMap)
}

module.exports = customTypeChecker
// app.js
var result = require('./custom-typechecker.js').getType(Buffer.from(''))
console.log(result)  // buffer

@dkebler
Copy link
Author

dkebler commented Jan 13, 2017

That didn't work as written. customTypeMap is neither exported nor passed into the new getType. I tried a few variations on this to no avail.

Did you mean this??
customTypeChecker.typeMap = {
would just overwrite the frozen type map and then nothing need be done to getTypes.

I tried that and that still fails. Got time to get this working for yourself first? I'll write a pr for the readme once it's working.


  it('Should include custom types', function () {
    expect(u.isBuffer(Buffer.from('this is a test'))).to.equal(true)
    expect(u.getType(Buffer.from('this is a test'))).to.equal('buffer')
  })

  1) Variable Types Library -  Should include custom types:

      AssertionError: expected 'object' to equal 'buffer'
      + expected - actual

      -object
      +buffer

@balupton
Copy link
Member

balupton commented Jan 13, 2017

Update previous example, should work.

@balupton
Copy link
Member

@dkebler okay, my updated code should work, but there is a bug in typechecker, so I'll update the code

@balupton
Copy link
Member

@dkebler okay, v4.4.1 is fixed, which makes the above work

@balupton
Copy link
Member

balupton commented Jan 18, 2017

the customTypeMap definition could also be done like so:

// Add our custom types
const customTypeMap = {
	buffer: Buffer.isBuffer
}
// Add original types
Object.keys(typechecker.typeMap).forEach(function (key) {
	customTypeMap[key] = customTypeMap[key] || typechecker.typeMap[key]
})

@dkebler
Copy link
Author

dkebler commented Jan 19, 2017

@balupton thanks! Now I can all add my classes as types :-).

I definitely preferred merging the maps (cleaner) but your object.keys statement above wasn't doing it. So here is the final working module. I'll do a PR for the readme and add this with some explanation.
again thx.

//mytypechecker.js

const typechecker = require('typechecker')
const customTypeChecker = Object.assign({}, typechecker)

// add custom types, a key and corresponding function for each
customTypeChecker.isBuffer = function isBuffer(obj) {
  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}

// Create a custom type map and make an key/property for each new type 
// the key/property used will be the string returned by getType. 
let customTypeMap = {
  buffer: customTypeChecker.isBuffer
}

// merge base typeMap with customTypeMap
customTypeMap = Object.assign(customTypeMap, customTypeChecker.typeMap)

//overwrite getType to use customTypeMap if available
customTypeChecker.getType = function customGetType(value, _typeMap) {
  return typechecker.getType(value, _typeMap || customTypeMap)
}

module.exports = customTypeChecker

@balupton
Copy link
Member

Glad it works :-)

I definitely preferred merging the maps (cleaner) but your object.keys statement above wasn't doing it.

Whoops fixed.

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

2 participants