🏨 Built-in transformations
JavaScript
remove unused variables
function show() {
- const message = 'hello';
console.log('hello world');
}remove duplicates from logical expressions
-a && b && a
+a && bremove unused for-of variables
-for (const {a, b} of c) {
+for (const {a} of c) {
console.log(a);
}remove unreferenced variables
-let a;
- a = 1;
let b;
b = 2;
console.log(b);remove duplicate keys
const a = {
- x: 'hello',
- ...y,
x: 'world',
...y,
}remove duplicate case
switch (x) {
case 5:
console.log('hello');
break;
- case 5:
- console.log('zz');
- break;
}remove unused private fields
class Hello {
#a = 5;
- #b = 3;
get() {
return this.#a;
};
}remove unused expressions
function show(error) {
- showError;
}remove useless variables
- function hi(a) {
- const b = a;
};
+ function hi(b) {
};remove useless new(why (opens in a new tab))
-new Error('something when wrong');
+Error('something when wrong');remove useless constructor(why (opens in a new tab))
-const s = String('hello');
+const s = 'hello';remove useless map
-const [str] = lines.map((line) => `hello ${line}`);
+const [line] = lines;
+const str = `hello ${line}`;remove useless continue
-for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
- continue;
+for (sign = decpt, i = 0; (sign /= 10) != 0; i++);remove useless operand
-a = a + b;
+a += b;remove useless return
-module.exports.traverse = ({push}) => {
- return {
- ObjectExpression(path) {
- }
- }
-};
+module.exports.traverse = ({push}) => ({
+ ObjectExpression(path) {
+ }
+});remove useless array constructor
-const a = Array(1, 2, 3);
+const a = [1, 2, 3];remove useless conditions
-if (zone?.tooltipCallback) {
- zone.tooltipCallback(e);
-}
+zone?.tooltipCallback(e);remove useless type conversion
-const a = Boolean(b.includes(c));
+const a = b.includes(c);
--if (!!a)
++if (a)
console.log('hi');
remove useless functions
-const f = (...a) => fn(...a);
-array.filter((a) => a);
+const f = fn;
+array.filter(Boolean);remove useless typeof
- typeof typeof 'hello';
+ typeof 'hello';declare undefined variables
const fs = import 'fs/promises';
const {stub} = import 'supertape';
+const {assign} = Object;
const readFile = stub();
assign(fs, {
readFile,
});remove useless arguments
onIfStatement({
push,
- generate,
- abc,
})
function onIfStatement({push}) {
}remove useless template expressions
-let y = `${"hello"} + ${"world"}`;
+let y = `hello + world`;remove useless for-of
-for (const a of ['hello']) {
- console.log(a);
-}
+console.log('hello');remove useless array.entries() (opens in a new tab)
-for (const [, element] of array.entries()) {
-}
+for (const element of array) {
+}reuse duplicateinit
const putout = require('putout');
-const {operator} = require('putout');
+const {operator} = putout;convert assignment to arrow function
-const createRegExp = (a) = RegExp(a, 'g');
+const createRegExp = (a) => RegExp(a, 'g');convert assignment to comparison
-if (a = 5) {
+if (a === 5) {
}convert quotes to backticks
-const a = 'hello \'world\'';
+const a = `hello 'world'`;convert typeof to is type
+const isFn = (a) => typeof a === 'function';
+
+if (isFn(fn))
-if (typeof fn === 'function')
fn();convert bitwise to logical
-a | !b
+a || !bconvert equal to strict equal
-if (a == b) {
+if (a === b) {
}convert indexOf to includes
-if (~array.indexOf(element)) {
+if (array.includes(element)) {
}remove useless escape
-const t = 'hello \"world\"';
-const s1 = `hello \"world\"`;
-const s = `hello \'world\'`;
+const t = 'hello "world"';
+const s1 = `hello "world"`;
+const s = `hello 'world'`;remove useless Array.from
-for (const x of Array.from(y)) {}
+for (const x of y) {}remove useless spread
-for (const x of [...y]) {}
+for (const x of y) {}remove debugger statement
- debugger;remove iife
-(function() {
- console.log('hello world');
-}());
+console.log('hello world');remove boolean from assertions
-if (a === true)
+if (a)
alert();remove boolean from logical expressions
-const t = true && false;
+const t = false;remove nested blocks
for (const x of Object.keys(a)) {
- {
- console.log(x);
- }
+ console.log(x);
}remove unreachable code
function hi() {
return 5;
- console.log('hello');
}split variable declarations
-let a, b;
+let a;
+let b;split nested destructuring
-const {a: {b}} = c;
+const {a} = c;
+const {b} = a;simplify assignment
-const {a} = {a: 5};
-const [b] = [5];
+const a = 5;
+const b = 5;simplify logical expressions
-!(options && !options.bidirectional);
+!options || options.bidirectional;simplify ternary
-module.exports = fs.copyFileSync ? fs.copyFileSync : copyFileSync;
+module.exports = fs.copyFileSync || copyFileSync;remove console.log calls
-console.log('hello');remove empty block statements
-if (x > 0) {
-}remove empty patterns
-const {} = process;remove strict mode directive from esm
-'use strict';
-
import * from fs;Add strict mode directive in commonjs if absent
+'use strict';
+
const fs = require('fs');remove constant conditions
function hi(a) {
- if (2 < 3) {
- console.log('hello');
- console.log('world');
- }
+ console.log('hello');
+ console.log('world');
};
function world(a) {
- if (false) {
- console.log('hello');
- console.log('world');
- }
};convert esm to commonjs (disabled)
-import hello from 'world';
+const hello = require('world');convert commonjs to esm (disabled)
-const hello = require('world');
+import hello from 'world';convert replace to replaceAll (stage-4 (opens in a new tab))
-'hello'.replace(/hello/g, 'world');
+'hello'.replaceAll('hello', 'world');apply destructuring
-const hello = world.hello;
-const a = b[0];
+const {hello} = world;
+const [a] = b;apply await import
-const {readFile} = import('fs/promises');
+const {readFile} = await import('fs/promises');apply if condition
-if (2 > 3);
+if (2 > 3)
alert();apply isArray (opens in a new tab)
-x instanceof Array;
+Array.isArray(x);apply Array.at(not bundled (opens in a new tab))
-const latest = (a) => a[a.length - 1];
+const latest = (a) => a.at(-1);apply numeric separators(proposal-numeric-separator (opens in a new tab))
-const a = 100000000;
+const a = 100_000_000;apply optional chaining (proposal-optional-chaining (opens in a new tab))
-const result = hello && hello.world;
+const result = hello?.world;apply nullish coalescing (proposal-nullish-coalescing (opens in a new tab), not bundled)
-result = typeof result === 'undefined' ? 'hello': result;
result = result ?? 'hello';convert throw statement into expression (proposal-throw-expressions (opens in a new tab), not bundled)
-const fn = (a) => {throw Error(a);}
+const fn = (a) => throw Error(a);merge destructuring properties
-const {one} = require('numbers'):
-const {two} = require('numbers');
+ const {
+ one,
+ two
+} = require('numbers');merge duplicate imports
-import {m as b} from 'y';
-import {z} from 'y';
-import x from 'y';
+import x, {m as b, z} from 'y';merge if statements
-if (a > b)
- if (b < c)
- console.log('hi');
+if (a > b && b < c)
+ console.log('hi');convert Math.pow to exponentiation operator
-Math.pow(2, 4);
+2 ** 4;convert anonymous to arrow function
-module.exports = function(a, b) {
+module.exports = (a, b) => {
}convert for to for-of
-for (let i = 0; i < items.length; i++) {
+for (const item of items) {
- const item = items[i];
log(item);
}convert forEach to for-of
-Object.keys(json).forEach((name) => {
+for (const name of Object.keys(json)) {
manage(name, json[name]);
-});
+}convert for-in to for-of
-for (const name in object) {
- if (object.hasOwnProperty(name)) {
+for (const name of Object.keys(object)) {
console.log(a);
- }
}convert map to for-of
-names.map((name) => {
+for (const name of names) {
alert(`hello ${name}`);
+}
-});convert array copy to slice
-const places = [
- ...items,
-];
+const places = items.slice();extract sequence expressions
-module.exports.x = 1,
-module.exports.y = 2;
+module.exports.x = 1;
+module.exports.y = 2;extract object properties into variable
-const {replace} = putout.operator;
-const {isIdentifier} = putout.types;
+const {operator, types} = putout;
+const {replace} = operator;
+const {isIdentifier} = types;convert apply to spread
-console.log.apply(console, arguments);
+console.log(...arguments);convert concat to flat
-[].concat(...array);
+array.flat();convert arguments to rest
-function hello() {
- console.log(arguments);
+function hello(...args) {
+ console.log(args);
}convert Object.assign to merge spread
function merge(a) {
- return Object.assign({}, a, {
- hello: 'world'
- });
+ return {
+ ...a,
+ hello: 'world'
+ };
};convert comparison to boolean
- const a = b === b;
+ const a = true;Promises
remove useless await
- await await Promise.resolve('hello');
+ await Promise.resolve('hello');remove useless async
-const show = async () => {
+const show = () => {
console.log('hello');
};add missing await
-runCli();
+await runCli();
async function runCli() {
}add await to return promise() statements (because it's faster, produces call stack and more readable (opens in a new tab))
async run () {
- return promise();
+ return await promise();
}apply top-level-await (proposal-top-level-await (opens in a new tab), enabled for ESM)
import fs from 'fs';
-(async () => {
- const data = await fs.promises.readFile('hello.txt');
-})();
+const data = await fs.promises.readFile('hello.txt');remove useless Promise.resolve
async () => {
- return Promise.resolve('x');
+ return 'x';
}convert Promise.reject to throw
async () => {
- return Promise.reject('x');
+ throw 'x';
}Node.js
convert fs.promises to fs/promises for node.js (opens in a new tab)
-const {readFile} = require('fs').promises;
+const {readFile} = require('fs/promises');convert top-level return into process.exit()(because EcmaScript Modules doesn't support top level return)
- return;
+ process.exit();remove process.exit call
-process.exit();Tape
replace test.only with test calls
-test.only('some test here', (t) => {
+test('some test here', (t) => {
t.end();
});replace test.skip with test calls
-test.skip('some test here', (t) => {
+test('some test here', (t) => {
t.end();
});TypeScript
remove duplicates from union
-type x = boolean[] | A | string | A | string[] | boolean[];
+type x = boolean[] | A | string | string[];convert generic to shorthand(why (opens in a new tab))
interface A {
- x: Array<X>;
+ x: X[];
}remove useless types from constants
-const x: any = 5;
+const x = 5;remove useless mapped types (opens in a new tab)
-type SuperType = {
- [Key in keyof Type]: Type[Key]
-}
+type SuperType = Type;remove useless mapping modifiers (opens in a new tab)
type SuperType = {
- +readonly[Key in keyof Type]+?: Type[Key];
+ readonly[Key in keyof Type]?: Type[Key];
}remove useless types
type oldType = number;
-type newType = oldType;
-const x: newType = 5;
+const x: oldType = 5;remove duplicate interface keys
interface Hello {
- 'hello': any;
'hello': string;
}remove unused types
type n = number;
-type s = string;
const x: n = 5;apply as type assertion (according to best practices (opens in a new tab))
-const boundaryElement = <HTMLElement>e.target;
+const boundaryElement1 = e.target as HTMLElement;apply utility types (opens in a new tab)
-type SuperType = {
- [Key in keyof Type]?: Type[Key];
-}
+type SuperType = Partial<Type>;