🏨 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 && b
remove 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 || !b
convert 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>;