Skip to content

Instantly share code, notes, and snippets.

@ankon
Last active February 21, 2020 12:05
Show Gist options
  • Save ankon/949ee3581fc1111665f3820bc1493af3 to your computer and use it in GitHub Desktop.
Save ankon/949ee3581fc1111665f3820bc1493af3 to your computer and use it in GitHub Desktop.
jscodeshift experiment: Object.keys(thing).map(k => thing[k]) --> Object.values(thing)
import { FileInfo, API, MemberExpression, CallExpression, Identifier } from 'jscodeshift';
function isExpression<T>(object: any, type: string): object is T {
return object.hasOwnProperty('type') && object.type === type;
}
function isMemberExpression(object: any): object is MemberExpression {
return isExpression<MemberExpression>(object, 'MemberExpression');
}
function isIdentifier(object: any): object is Identifier {
return isExpression<Identifier>(object, 'Identifier');
}
function objectKeysMapToValues(fileInfo: FileInfo, api: API) {
const j = api.jscodeshift;
const root = j(fileInfo.source);
root.find(j.CallExpression, {
callee: {
type: 'MemberExpression',
object: {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: 'Object'
},
property: {
type: 'Identifier',
name: 'keys'
},
},
},
property: {
type: 'Identifier',
name: 'map',
},
},
})
.replaceWith(nodePath => {
const { node } = nodePath;
// Ignore all nodes that are not "trivial", i.e. where the map is not a simple arrow expression
const mapArgument = node.arguments[0];
if (mapArgument.type !== 'ArrowFunctionExpression') {
return node;
}
if (!isMemberExpression(mapArgument.body)) {
return node;
}
if (!isIdentifier(mapArgument.params[0])) {
return node;
}
const keysArgument = ((node.callee as MemberExpression).object as CallExpression).arguments[0];
if (!isIdentifier(keysArgument)) {
return node;
}
if (!(isIdentifier(mapArgument.body.object) && mapArgument.body.object.name === keysArgument.name)) {
return node;
}
if (!(isIdentifier(mapArgument.body.property) && mapArgument.body.property.name === mapArgument.params[0].name)) {
return node;
}
// Do the replacing with a simple 'Object.values(thing)
return j.callExpression(
j.memberExpression(j.identifier('Object'), j.identifier('values')),
[j.identifier(keysArgument.name)]);
});
return root.toSource();
}
// Export for jscodeshift
objectKeysMapToValues.parser = 'ts';
export = objectKeysMapToValues;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment