# 🏨 Built-in transformations

# JavaScript

remove unused variables
  function show() {
-     const message = 'hello';
      console.log('hello world');
  }
1
2
3
4
remove duplicates from logical expressions
-a && b && a
+a && b
1
2
remove unused for-of variables
-for (const {a, b} of c) {
+for (const {a} of c) {
    console.log(a);
}
1
2
3
4
remove unreferenced variables
-let a;
- a = 1;
let b;
b = 2;
console.log(b);
1
2
3
4
5
remove duplicate keys
const a = {
-   x: 'hello',
-   ...y,
    x: 'world',
    ...y,
}
1
2
3
4
5
6
remove duplicate case
switch (x) {
    case 5:
        console.log('hello');
        break;
-   case 5:
-       console.log('zz');
-       break;
}
1
2
3
4
5
6
7
8
remove unused private fields
  class Hello {
    #a = 5;
-   #b = 3;
    get() {
        return this.#a;
    };
}
1
2
3
4
5
6
7
remove unused expressions
  function show(error) {
-     showError;
  }
1
2
3
remove useless variables
-   function hi(a) {
-       const b = a;
    };
+   function hi(b) {
    };
1
2
3
4
5
remove useless new(why)
-new Error('something when wrong');
+Error('something when wrong');
1
2
remove useless constructor(why)
-const s = String('hello');
+const s = 'hello';
1
2
remove useless map
-const [str] = lines.map((line) => `hello ${line}`);
+const [line] = lines;
+const str = `hello ${line}`;
1
2
3
remove useless continue
-for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
-    continue;
+for (sign = decpt, i = 0; (sign /= 10) != 0; i++);
1
2
3
remove useless operand
-a = a + b;
+a += b;
1
2
remove useless return
-module.exports.traverse = ({push}) => {
-    return {
-        ObjectExpression(path) {
-        }
-    }
-};
+module.exports.traverse = ({push}) => ({
+    ObjectExpression(path) {
+    }
+});
1
2
3
4
5
6
7
8
9
10
remove useless array constructor
-const a = Array(1, 2, 3);
+const a = [1, 2, 3];
1
2
remove useless conditions
-if (zone?.tooltipCallback) {
-    zone.tooltipCallback(e);
-}
+zone?.tooltipCallback(e);
1
2
3
4
remove useless type conversion
-const a = Boolean(b.includes(c));
+const a = b.includes(c);

--if (!!a)
++if (a)
    console.log('hi');

1
2
3
4
5
6
7
remove useless functions
-const f = (...a) => fn(...a);
-array.filter((a) => a);

+const f = fn;
+array.filter(Boolean);
1
2
3
4
5
remove useless typeof
- typeof typeof 'hello';
+ typeof 'hello';
1
2
declare undefined variables
const fs = import 'fs/promises';
const {stub} = import 'supertape';

+const {assign} = Object;

const readFile = stub();

assign(fs, {
    readFile,
});
1
2
3
4
5
6
7
8
9
10
remove useless arguments
onIfStatement({
    push,
-   generate,
-   abc,
})

function onIfStatement({push}) {
}
1
2
3
4
5
6
7
8
remove useless template expressions
-let y = `${"hello"} + ${"world"}`;
+let y = `hello + world`;
1
2
remove useless for-of
-for (const a of ['hello']) {
-    console.log(a);
-}
+console.log('hello');
1
2
3
4
remove useless array.entries()
-for (const [, element] of array.entries()) {
-}
+for (const element of array) {
+}
1
2
3
4
reuse duplicateinit
const putout = require('putout');
-const {operator} = require('putout');
+const {operator} = putout;
1
2
3
convert assignment to arrow function
-const createRegExp = (a) = RegExp(a, 'g');
+const createRegExp = (a) => RegExp(a, 'g');
1
2
convert assignment to comparison
-if (a = 5) {
+if (a === 5) {
}
1
2
3
convert quotes to backticks
-const a = 'hello \'world\'';
+const a = `hello 'world'`;
1
2
convert typeof to is type
+const isFn = (a) => typeof a === 'function';
+
+if (isFn(fn))
-if (typeof fn === 'function')
    fn();
1
2
3
4
5
convert bitwise to logical
-a | !b
+a || !b
1
2
convert equal to strict equal
-if (a == b) {
+if (a === b) {
}
1
2
3
convert indexOf to includes
-if (~array.indexOf(element)) {
+if (array.includes(element)) {
}
1
2
3
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'`;
1
2
3
4
5
6
remove useless Array.from
-for (const x of Array.from(y)) {}
+for (const x of y) {}
1
2
remove useless spread
-for (const x of [...y]) {}
+for (const x of y) {}
1
2
remove debugger statement
- debugger;
1
remove iife
-(function() {
-    console.log('hello world');
-}());
+console.log('hello world');
1
2
3
4
remove boolean from assertions
-if (a === true)
+if (a)
    alert();
1
2
3
remove boolean from logical expressions
-const t = true && false;
+const t = false;
1
2
remove nested blocks
for (const x of Object.keys(a)) {
-   {
-       console.log(x);
-   }
+   console.log(x);
}
1
2
3
4
5
6
remove unreachable code
function hi() {
    return 5;
-   console.log('hello');
}
1
2
3
4
split variable declarations
-let a, b;
+let a;
+let b;
1
2
3
split nested destructuring
-const {a: {b}} = c;
+const {a} = c;
+const {b} = a;
1
2
3
simplify assignment
-const {a} = {a: 5};
-const [b] = [5];
+const a = 5;
+const b = 5;
1
2
3
4
simplify logical expressions
-!(options && !options.bidirectional);
+!options || options.bidirectional;
1
2
simplify ternary
-module.exports = fs.copyFileSync ? fs.copyFileSync : copyFileSync;
+module.exports = fs.copyFileSync || copyFileSync;
1
2
remove console.log calls
-console.log('hello');
1
remove empty block statements
-if (x > 0) {
-}
1
2
remove empty patterns
-const {} = process;
1
remove strict mode directive from esm
-'use strict';
-
import * from fs;
1
2
3
Add strict mode directive in commonjs if absent
+'use strict';
+
const fs = require('fs');
1
2
3
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');
-   }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
convert esm to commonjs (disabled)
-import hello from 'world';
+const hello = require('world');
1
2
convert commonjs to esm (disabled)
-const hello = require('world');
+import hello from 'world';
1
2
convert replace to replaceAll (stage-4)
-'hello'.replace(/hello/g, 'world');
+'hello'.replaceAll('hello', 'world');
1
2
apply destructuring
-const hello = world.hello;
-const a = b[0];
+const {hello} = world;
+const [a] = b;
1
2
3
4
apply await import
-const {readFile} = import('fs/promises');
+const {readFile} = await import('fs/promises');
1
2
apply if condition
-if (2 > 3);
+if (2 > 3)
    alert();
1
2
3
apply isArray
-x instanceof Array;
+Array.isArray(x);
1
2
apply Array.at(not bundled)
-const latest = (a) => a[a.length - 1];
+const latest = (a) => a.at(-1);
1
2
apply numeric separators(proposal-numeric-separator)
-const a = 100000000;
+const a = 100_000_000;
1
2
apply optional chaining (proposal-optional-chaining)
-const result = hello && hello.world;
+const result = hello?.world;
1
2
apply nullish coalescing (proposal-nullish-coalescing, not bundled)
-result = typeof result  === 'undefined' ? 'hello': result;
result = result ?? 'hello';
1
2
convert throw statement into expression (proposal-throw-expressions, not bundled)
-const fn = (a) => {throw Error(a);}
+const fn = (a) => throw Error(a);
1
2
merge destructuring properties
-const {one} = require('numbers'):
-const {two} = require('numbers');
+ const {
+   one,
+   two
+} = require('numbers');
1
2
3
4
5
6
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';
1
2
3
4
merge if statements
-if (a > b)
-    if (b < c)
-        console.log('hi');
+if (a > b && b < c)
+    console.log('hi');
1
2
3
4
5
convert Math.pow to exponentiation operator
-Math.pow(2, 4);
+2 ** 4;
1
2
convert anonymous to arrow function
-module.exports = function(a, b) {
+module.exports = (a, b) => {
}
1
2
3
convert for to for-of
-for (let i = 0; i < items.length; i++) {
+for (const item of items) {
-   const item = items[i];
    log(item);
}
1
2
3
4
5
convert forEach to for-of
-Object.keys(json).forEach((name) => {
+for (const name of Object.keys(json)) {
    manage(name, json[name]);
-});
+}
1
2
3
4
5
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);
-   }
}
1
2
3
4
5
6
convert map to for-of
-names.map((name) => {
+for (const name of names) {
    alert(`hello ${name}`);
+}
-});
1
2
3
4
5
convert array copy to slice
-const places = [
-    ...items,
-];
+const places = items.slice();
1
2
3
4
extract sequence expressions
-module.exports.x = 1,
-module.exports.y = 2;
+module.exports.x = 1;
+module.exports.y = 2;
1
2
3
4
extract object properties into variable
-const {replace} = putout.operator;
-const {isIdentifier} = putout.types;
+const {operator, types} = putout;
+const {replace} = operator;
+const {isIdentifier} = types;
1
2
3
4
5
convert apply to spread
-console.log.apply(console, arguments);
+console.log(...arguments);
1
2
convert concat to flat
-[].concat(...array);
+array.flat();
1
2
convert arguments to rest
-function hello() {
-    console.log(arguments);
+function hello(...args) {
+    console.log(args);
}
1
2
3
4
5
convert Object.assign to merge spread
function merge(a) {
-   return Object.assign({}, a, {
-       hello: 'world'
-   });
+   return {
+       ...a,
+       hello: 'world'
+   };
};
1
2
3
4
5
6
7
8
9
convert comparison to boolean
-   const a = b === b;
+   const a = true;
1
2

# Promises

remove useless await
-   await await Promise.resolve('hello');
+   await Promise.resolve('hello');
1
2
remove useless async
-const show = async () => {
+const show = () => {
    console.log('hello');
};
1
2
3
4
add missing await
-runCli();
+await runCli();

async function runCli() {
}
1
2
3
4
5
add await to return promise() statements (because it's faster, produces call stack and more readable)
async run () {
-   return promise();
+   return await promise();
}
1
2
3
4
apply top-level-await (proposal-top-level-await, enabled for ESM)
import fs from 'fs';

-(async () => {
-    const data = await fs.promises.readFile('hello.txt');
-})();
+const data = await fs.promises.readFile('hello.txt');
1
2
3
4
5
6
remove useless Promise.resolve
async () => {
-    return Promise.resolve('x');
+    return 'x';
}
1
2
3
4
convert Promise.reject to throw
async () => {
-    return Promise.reject('x');
+    throw 'x';
}
1
2
3
4

# Node.js

convert fs.promises to fs/promises for node.js
-const {readFile} = require('fs').promises;
+const {readFile} = require('fs/promises');
1
2
convert top-level return into process.exit()(because EcmaScript Modules doesn't support top level return)
-   return;
+   process.exit();
1
2
remove process.exit call
-process.exit();
1

# Tape

replace test.only with test calls
-test.only('some test here', (t) => {
+test('some test here', (t) => {
    t.end();
});
1
2
3
4
replace test.skip with test calls
-test.skip('some test here', (t) => {
+test('some test here', (t) => {
    t.end();
});
1
2
3
4

# TypeScript

remove duplicates from union
-type x = boolean[] | A | string | A | string[] | boolean[];
+type x = boolean[] | A | string | string[];
1
2
convert generic to shorthand(why)
interface A {
-    x: Array<X>;
+    x: X[];
}
1
2
3
4
remove useless types from constants
-const x: any = 5;
+const x = 5;
1
2
remove useless mapped types
-type SuperType = {
-   [Key in keyof Type]: Type[Key]
-}
+type SuperType = Type;
1
2
3
4
remove useless mapping modifiers
type SuperType = {
-   +readonly[Key in keyof Type]+?: Type[Key];
+   readonly[Key in keyof Type]?: Type[Key];
}
1
2
3
4
remove useless types
type oldType = number;
-type newType = oldType;
-const x: newType = 5;
+const x: oldType = 5;
1
2
3
4
remove duplicate interface keys
interface Hello {
-   'hello': any;
    'hello': string;
}
1
2
3
4
remove unused types
type n = number;
-type s = string;
const x: n = 5;
1
2
3
apply as type assertion (according to best practices)
-const boundaryElement = <HTMLElement>e.target;
+const boundaryElement1 = e.target as HTMLElement;
1
2
apply utility types
-type SuperType = {
-    [Key in keyof Type]?: Type[Key];
-}
+type SuperType = Partial<Type>;
1
2
3
4
Last Updated: 10 months ago