JetBrains Rider 2021.2 Help

Refactoring TypeScript

Refactoring means updating the source code without changing the behaviour of the application. Refactoring helps you keep your code solid, dry, and easy to maintain.

Move refactorings

Besides moving files and folders, JetBrains Rider lets you move TypeScript top-level symbols. The Move Symbol Refactoring works for classes, functions, and variables in ES6 modules.

Move a class, a function, or a variable

  1. Select the symbol to move.

  2. Press F6 or select Refactor | Move from the main menu or from the context menu of the selection. Alternatively, choose Refactor | Refactor This or press Ctrl+Alt+Shift+T, then choose Move from the list.

    The Move Module Members dialog opens.

  3. Specify the destination file and select the members to move.

  4. By default, JetBrains Rider automatically raises the visibility of the members to the required level. If you want to keep the visibility level unchanged, click As is in the Visibility.

Pull Class Members Up refactoring

The Pull Class Members Up refactoring moves class methods upwards in the class hierarchy – from the current class to a superclass or to the interface which it implements.

Suppose you have a class AccountingDepartment that extends an abstract class Department and implements an interface ReportingDepartment.

abstract class Department { constructor(public name: string) { } printName(): void { console.log("Department name: " + this.name); } } interface ReportingDepartment { generateReports(): void } class AccountingDepartment extends Department implements ReportingDepartment { constructor() { super("Accounting and Auditing"); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }

Example 1: Moving a class method to a superclass

In this example, the PrintMeeting() method is moved from AccountingDepartment to Department.

abstract class Department { constructor(public name: string) { } printName(): void { console.log("Department name: " + this.name); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } } interface ReportingDepartment { generateReports(): void } class AccountingDepartment extends Department implements ReportingDepartment { constructor() { super("Accounting and Auditing"); } generateReports(): void { console.log("Generating accounting reports..."); } }
Pulling a class method to a superclass

Example 2: Moving a class method to an interface

In this example, the PrintMeeting() method is copied from the AccountingDepartment class to the ReportingDepartment interface.

abstract class Department { constructor(public name: string) { } printName(): void { console.log("Department name: " + this.name); } } interface ReportingDepartment { generateReports(): void printMeeting(): void } class AccountingDepartment extends Department implements ReportingDepartment { constructor() { super("Accounting and Auditing"); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }

Move the methods of a class to a superclass or an interface

  1. Position the caret anywhere inside the class from which you want to pull the members up.

  2. Select Refactor | Pull Members Up from the main menu or from the context menunu. The Pull Members Up dialog opens.

  3. From the list, select the superclass or the interface where you want to move the methods.

  4. To pull a method up, select the checkbox next to it in the Members to be pulled up list. If applicable, select the Make abstract checkbox next to the method to move.

Rename refactorings

Besides Renaming files and folders, which is available in the context of any language, you can also rename classes, methods, variables, parameters, and fields. JetBrains Rider changes the name of the symbol in its declaration and by default all its usages in the current project.

Rename refactoring

The Rename refactoring is performed inplace, but you can press Shift+F6 to configure the refactoring scope in the Rename dialog.

To open the dialog by default, open the Settings/Preferences dialog Ctrl+Alt+S, go to Editor | Code editing, and select the In modal dialogs option in the Specify refactorings options area.

  1. In the editor, select the class, method, variable, or field to rename and press Shift+F6 or choose Refactor | Rename from the context menu or from the main menu.

  2. In the field with canvas, specify the new name of the symbol. Type the name or select an appropriate one from the list.

  3. Optionally:

    Click the Rename in comments and strings icon the Rename in text occurrences icon next to the highlighted symbol to open the Also rename in popup and select the Search in comments and strings and Search for text occurrences checkboxes to rename the usages of the symbol in comments, string literals, and text.

  4. Optionally:

    To open the Rename dialog with more options, press Shift+F6 once again.

    • Select the Search in comments and strings checkbox to rename the usages of the symbol in comments, documentation comments, and string literals.

    • Select the Search for text occurrences checkbox to rename the matched symbol in texts in HTML and other files included in the project.

    • Select the Search in JavaScript files checkbox to rename the usages of the symbol in generated JavaScript code.

    • Select the Search for dynamic references checkbox to rename the dynamic usages of the symbol.

      Note that including dynamic usages in the refactoring may cause erroneous renaming as shown in the example below. Here target in console.log(e.target) can be changed to myTarget because e has the type any, which means it could also be myInt.

      interface myInt { target: string } function onClick(e: any) { console.log(e.target); }
      interface myInt { myTarget: string } function onClick(e: any) { console.log(e.myTarget); }
  5. To avoid erroneous renaming, preview the changes before applying them.

    By default, in the Refactoring Preview tool window, all the dynamic usages of a symbol are marked as excluded and grouped under the Dynamic references in code to <symbol> node. To apply the refactoring to a usage, select Include from its context menu.

    Refactoring Preview: the dynamic usages of a symbol are marked as excluded from refactoring

Keep the names of classes and containing files in compliance

When you rename a class, JetBrains Rider also suggests renaming the file if it has the same name. If you accept the suggestion, JetBrains Rider updates the name of this file in import statements in other files.

If you reject this suggestion, you can rename the file at any time later using the Rename file... intention action. This is useful if you have just created a new file but then came up with a better name when started typing a class or interface in it.

Another intention action suggests moving the class to a new file with the corresponding name. The format of the suggested filename is determined by the style chosen from the Filename convention list on the Code Style: JavaScript page.

Keep the name of a file in compliance with the name of the corresponding class

  1. Position the caret at the name of the class and press Alt+Enter.

  2. From the intentions list, choose Rename file to <class_name.ts> to match class name or Move class <class_name> to file <class_name.ts>.

    Moving a class to a file keeping the names in compliance

Extract/Introduce refactorings

JetBrains Rider provides various Extract refactorings to introduce parameters, variables, constants, fields, methods, and functions. To run any of these refactorings, select the expression to refactor and choose Refactor | <target>. You can select an entire expression or position the caret anywhere inside it and JetBrains Rider will help you with the selection.

Introduce Parameter

Use the Introduce Parameter refactoring to replace an expression in the calls of a function with a parameter. JetBrains Rider will update the declaration and the calls of the function accordingly. The default value of the new parameter can be initialized inside the function body or passed through function calls.

Suppose you have a piece of code with a hardcoded "Hello, " in the function greeter().

function greeter(firstName : String, lastName : String) { return "Hello, " + firstName + " " + lastName; } document.body.innerHTML = greeter("Jane","User");
With the Introduce Parameter refactoring, you can replace this hardcoded "Hello, " with a greeting parameter. The new greeting parameter can be extracted as optional or as required.

Example 1: Extracting an optional parameter

A new parameter greeting is extracted as an optional parameter. The new parameter is added to the definition of greeter() using the function default parameter syntax. The call of greeter() is not changed.

function greeter(firstName : String, lastName : String, greeting = "Hello, ") { return greeting + firstName + " " + lastName; } document.body.innerHTML = greeter("Jane","User");

Example 2: Extracting a required parameter

In this example, a new parameter greeting is extracted as a required parameter. So the corresponding function call (document.body.innerHTML = greeter(user); is changed accordingly.

function greeter(firstName : String, lastName : String, greeting: string) { return greeting + firstName + " " + lastName; } document.body.innerHTML = greeter("Jane", "User", "Hello, ");

Introduce a parameter

  1. In the editor, position the caret within the expression that you want to convert into a parameter and press Ctrl+Alt+P or select Refactor | Introduce Parameter from the context menu.

    Alternatively, do one of the following:

    • Press Ctrl+Alt+Shift+T and select Introduce Parameter.

    • From the main menu, select Refactor | Extract | Parameter.

  2. If several expressions are detected in the current cursor location, select the required one from the Expressions list.

    Introduce Parameter: select an expression
  3. If more than one occurrence of the selected expression is found, select Replace this occurrence only or Replace all occurrences from the Multiple occurrences found list. Finally, the popup for configuring the refactoring appears.

    Introduce Parameter popup
  4. Select the Generate JSDoc to have a JSDoc comment block generated. This may be helpful if you need to specify a custom default parameter value. Learn more from the JSDoc official website.

  5. Choose where the new parameter will be initialized and specify its default value, if applicable:

    • If the Optional parameter checkbox is selected, the parameter will be initialized with the default value in the function body.

    • If the Optional parameter checkbox is cleared, the default parameter value will be passed through the existing function calls. All the function calls will change according to the new function signature and a parameter initialization will be added to the function body.

    Initially, JetBrains Rider accepts the expression where the refactoring is invoked as the default value. In most cases you do not need to change it. If it is still necessary, specify another default value in the JSDoc comment in the format @param <parameter name> - <default value>.

    Learn more about optional and default parameters from the TypeScript official website.

  6. Accept one of the suggested parameter names by double-clicking it in the list or specify a custom name in the field with red canvas. Press Enter when ready.

    Introduce Parameter: result

Choosing the refactoring mode

You can extract a parameter right in the editor (in the in-place mode) as described above or use the Introduce Parameter dialog. These two approaches are rather similar, the difference is as follows:

  • Previewing the results of the refactoring.

    In the dialog, you can click Preview and examine the expected changes in the dedicated tab of the Find tool window. In the in-place mode, this functionality is not available.

  • Specifying the default parameter value.

    In the dialog, JetBrains Rider suggests the default parameter value in the Value field where you can accept the suggestion or specify another value. In the in-place mode, JetBrains Rider treats the expression where the refactoring is invoked as the default parameter value. To specify another value, you have to use a JSDoc comment block.

Introduce Variable

Use the Introduce Variable refactoring to replace an expression with a function-scoped variable (var), a block-scoped variable (let), or a block-scoped constant (const). This refactoring makes your source code easier to read and maintain. It also helps you avoid using hardcoded constants without any explanations about their values or purposes.

function Multiplication(a : number, b : number) { let d = (a + b) * (a + b); return d; } var e = Multiplication(4, 6);
function Multiplication(a : number, b : number) { let c = a + b; let d = (c) * (c); return d; } var e = Multiplication(4, 6);

Introduce a variable

  1. In the editor, select the expression to convert into a variable and press Ctrl+Alt+V and select Refactor | Introduce Variable from the context menu.

    Alternatively, do one of the following:

    • Press Ctrl+Alt+Shift+T and select Introduce Variable.

    • From the main menu, select Refactor | Extract | Variable.

  2. If several expressions are detected in the current cursor location, select the required one from the Expressions list.

    Introduce Variable: select expression
  3. If more than one occurrence of the selected expression is found, select Replace this occurrence only or Replace all occurrences from the Multiple occurrences found list.

    Introduce Variable: multiple occurrences of the selected expression detected

    Finally, the popup for configuring the refactoring appears.

  4. From the list, select the statement to use in the declaration of the new variable:

    Introduce Variable: select the scope
  5. Accept one of the suggested parameter names by double-clicking it in the list or specify a custom name in the field with red canvas. Press Enter when ready.

Choosing the refactoring mode

You can extract a variable right in the editor (in the in-place mode) as described above or use the Introduce Variable dialog. By default, JetBrains Rider runs the Introduce Variable refactoring in the in-place mode. To use the Extract Variable dialog, open the Settings/Preferences dialog Ctrl+Alt+S, go to Editor | Code Editing, and select the In modal dialogs option in the Refactorings area.

Introduce Constant

Use the Introduce Constant refactoring to replace an expression with a constant. This refactoring makes your source code easier to read and maintain. It also helps you avoid using hardcoded constants without any explanations about their values or purposes.

Introducing constants in various scopes

Suppose you have a fragment of code with hardcoded Department name:.

printName(): void { console.log("Department name: " + this.name); }

With the Introduce Constant refactoring, you can replace the hardcoded Department name with a constant. The scope of the extracted constant depends on the context in which the new constant is declared (inside the enclosing method, as a field of the class, or outside any class).

Example 1: The introduced constant departmentName is declared inside the enclosing method printName()

printName(): void { console.log("Department name: " + this.name); }
printName(): void { const departmentName = "Department name: "; console.log(departmentName + this.name); }

Example 2: The introduced constant is declared as the _departmentName field of the enclosing class AccountingDepartment

class AccountingDepartment extends Department implements ReportingDepartment { name: string; printName(): void { console.log("Department name: " + this.name); } }
class AccountingDepartment extends Department implements ReportingDepartment { name: string; private readonly _departmentName = "Department name: "; printName(): void { console.log(this._departmentName + this.name); } }

Example 3: The introduced constant departmentName is declared outside any class

class AccountingDepartment extends Department implements ReportingDepartment { name: string; printName(): void { console.log("Department name: " + this.name); } }
abstract class Department {...} const deparmentName = "Department name: "; class AccountingDepartment extends Department implements ReportingDepartment {...}

Introduce a constant

  1. In the editor, select the expression to convert into a constant and press Ctrl+Alt+C or select Refactor | Introduce Constant from the context menu.

    Alternatively, do one of the following:

    • Press Ctrl+Alt+Shift+T and select Introduce Constant.

    • From the main menu, select Refactor | Extract | Constant.

    Invoke the Introduce Constant refactoring
  2. If several expressions are detected in the current cursor location, select the required one from the Expressions list.

    Introduce Constant: select the expression
  3. Select the scope for the new constant:

    • Local constant will be declared inside the enclosing method, see Example 1.

    • Class field will be declared inside the current class, see Example 2.

    • Global or module constant will be declared outside any class, see Example 3.

    Introduce Constant: select scope
  4. If JetBrains Rider detects several occurrences of the expression, select whether you want to replace all of them or only the one where the refactoring was invoked.

    Introduce Constant: multiple occurrences for global constant
  5. Accept one of the suggested parameter names by double-clicking it in the list or specify a custom name in the field with red canvas. Press Enter when ready.

    Introduce Constant: select the name

Introduce Field

The Introduce Field refactoring declares a new field and initializes it with the selected expression. The original expression is replaced with the usage of the field.

Suppose you have the following code:

class Rectangle { constructor(public height: number, public width: number) { this.height = height; this.width = width; } get area() { return this.calcArea(); } calcArea() { return this.height * this.width; } }
In all the three examples below, the same field, _calcArea is introduced. The examples illustrate three different ways to initialize the introduced field.

Example 1: The introduced field _calcAreais initialized in the enclosing method get Area()

class Rectangle { constructor(public height: number, public width: number) { this.height = height; this.width = width; } private _calcArea: number; get area() { this._calcArea = this.calcArea(); return this._calcArea; } calcArea() { return this.height * this.width; } }

Example 2: The introduced field _calcArea is initialized in its declaration

class Rectangle { constructor(public height: number, public width: number) { this.height = height; this.width = width; } private _calcArea = this.calcArea(); get area() { return this._calcArea; } calcArea() { return this.height * this.width; } }

Example 3: The introduced field _calcArea is initialized in the constructor of the class

class Rectangle { constructor(public height: number, public width: number) { this._calcArea = this.calcArea(); this.height = height; this.width = width; } private _calcArea: number; get area() { return this._calcArea; } calcArea() { return this.height * this.width; } }

Introduce a field

  1. In the editor, select the expression to convert into a constant and press Ctrl+Alt+F or select Refactor | Introduce Field from the context menu.

    Alternatively, do one of the following:

    • Press Ctrl+Alt+Shift+T and select Introduce Field.

    • From the main menu, select Refactor | Extract | Field.

  2. If JetBrains Rider detects several occurrences of the expression, select whether you want to replace all of them or only the one where the refactoring was invoked.

    Extract field in TypeScript: several occurrences of an expression detected
  3. In the popup, choose where the new field will be initialized:

    • Current method, see Example 1.

    • Field declaration, see Example 2.

    • Constructor, see Example 3. Note that this option is disabled if you invoke the refactoring from a field initializer.

    Extract field in TypeScript: choose initialization
  4. When initialized in a field declaration or in a constructor, the new field can be introduced with a readonly modifier. To do that, select the Make readonly checkbox.

  5. Choose the field visibility, the available options are Public, Private, and Protected. Learn about field visibility modifiers from the TypeScript official website

  6. Accept one of the suggested parameter names by double-clicking it in the list or specify a custom name in the field with red canvas. Press Enter when ready.

Choosing the refactoring mode

By default, JetBrains Rider runs the Introduce Field refactoring right in the editor (in the in-place mode), as described above.

To use the Extract Field Dialog, open the Settings/Preferences dialog Ctrl+Alt+S, go to Editor | Code Editing, and select the In modal dialogs option in the Refactorings area.

Refactoring TypeScript: Introduce Field

Extract Method

The Extract Method refactoring lets you create a named method or function with the extracted code. When the Extract Method refactoring is invoked, JetBrains Rider detects the variables that are the input for the selected code fragment and the variable that is the output for it. The detected output variable is used as the return value for the extracted method or function.

Example 1: Extracting a global method from an expression inside another method

In this example, a globally scoped method NewMethod() is extracted from the let c = a + b; expression. The parameters for the extracted method are retrieved from the let c = a + b; expression.

Example 1.1: A function declaration is generated

function MyFunction(a : number, b : number) { let c = a + b; let d = c * c; return d; }
function NewMethod(a: number, b: number) { let c = a + b; return c; } function MyFunction(a : number, b : number) { let c = NewMethod(a, b); let d = c * c; return d; }

Example 1.2: The extracted function is declared inside an expression

function MyFunction(a : number, b : number) { let c = a + b; let d = c * c; return d; }
let NewMethod = function (a: number, b: number) { let c = a + b; return c; }; function MyFunction(a : number, b : number) { let c = NewMethod(a, b); let d = c * c; return d; }

Example 2: Extracting a method with declaration inside the enclosing method

In this example, a method NewMethod() is extracted from the let c = a + b; expression. The destination scope function MyFunction is chosen.

function MyFunction(a : number, b : number) { let c = a + b; let d = c * c; return d; }
function MyFunction(a : number, b : number) { let NewMethod = function () { let c = a + b; return c; }; let c = NewMethod(); let d = c * c; return d; }

Example 3: Extracting a method from an expression outside any method

A method NewMethod() is extracted from the var e = MyFunction(4, 6); expression that is outside any method. The extracted method is globally scoped.

var e = MyFunction(4, 6);
let NewMethod = function () { var e = MyFunction(4, 6); }; NewMethod();

Extract a function

  1. In the editor, select a code fragment to convert into a function and press Ctrl+Alt+M or select Refactor | Extract Method from the context menu.

    Alternatively, do one of the following:

    • Press Ctrl+Alt+Shift+T and select Extract Method.

    • From the main menu, select Refactor | Extract | Method.

  2. If the selected expression is inside another function, choose the destination scope from the list:

    ws_ts_extract_method_choose_scope.png
    • If you choose global, the extracted function will be declared outside any function, see Example 1 above.

    • To declare the extracted function inside the current enclosing function, choose function <current enclosing function name>, see Example 2 above.

  3. To open the Extract Function dialog with more options, press Ctrl+Alt+M once again. In this dialog, you can choose whether the extracted function will be declared through a generated function declaration or inside an expression and configure the set of variables to be passed as parameters. See Examples above.

    ws_ts_extract_method_dialog.png

Open the Extract Function dialog by default

  • open the Settings/Preferences dialog Ctrl+Alt+S, go to Editor | Code Editing, and select the In modal dialogs option in the Refactorings area.

Extract Type Alias

Use this refactoring to convert a type declaration expression into a type alias and replace all the occurrences of this expressions with this alias.

ws_ts_type_alias_to_interface.png

Suppose you have the following fragment of code with a { z: number } type declaration:

function returnsObj(): { x : number, y : {z : number} } { return null } function anotherObjectReturned(): {x : number, y : {z : number} } { return null }
In the example below, a type alias MyNewAlias is extracted from the { z: number } type declaration:
type MyNewAlias = { z : number }; function returnsObj(): { x : number, y : MyNewAlias } { return null } function anotherObjectReturned(): { x : number, y : MyNewAlias } { return null }

Extract a type alias

  1. In the editor, position the caret within the expression that you want to replace with a type alias and select Refactor | Extract Type Alias from the context menu or Refactor | Extract | Type Alias from the main menu.

  2. If several expressions are detected in the current cursor location, select the required one from the Expressions list.

    ws_ts_extract_type_alias_select_type_declaration_expression.png
  3. If more than one occurrence of the selected expression is found, select Replace this occurrence only or Replace all occurrences from the Multiple occurrences found list.

    ws_ts_extract_type_alias_multiple_occurrences.png
  4. In the field, type the name of the type alias and press Enter when ready.

    ws_ts_extract_type_alias_specify_name.png

Extract Superclass

The Extract Superclass refactoring creates a new abstract class based on the members of the current class. The created abstract class is extended automatically.

Suppose you have a class AccountingDepartment and you expect that the printName() method from it will be re-used.

class AccountingDepartment { name: string; printName(): void { console.log("Department name: " + this.name); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }
You can extract a superclass Department and include the printName and the Name field in it.
class Department { name: string; printName(): void { console.log("Department name: " + this.name); } } class AccountingDepartment extends Department { printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }

Extract a superclass

  1. Position the caret anywhere inside the class from which you want to extract a superclass.

  2. Select Refactor | Extract | Superclass from the main menu or Refactor | Extract Superclass from the context menu. The Extract Superclass dialog opens.

  3. Specify the name of the new superclass and select the checkboxes next to the class members you want to include in it.

  4. In the Destination file field, specify the location of the file where the new class will be. By default, the field shows the path to the current file where the refactoring was invoked.

  5. Choose Extract Superclass. JetBrains Rider creates a new class and marks the source class with extends.

    To create a superclass and replace the references to the source class with references to the superclass in parameters of methods, choose Extract superclass and use it where possible. JetBrains Rider shows the proposed changes in the Refactoring Preview pane of the Find tool window.

Extract Interface

The Extract Interface refactoring creates a new interface based on the members of the current class. The created interface will be implemented automatically.

Suppose you have a class AccountingDepartment and you expect that the generateReports() method from it will have other implementations.

abstract class Department { constructor(public name: string) { } printName(): void { console.log("Department name: " + this.name); } } class AccountingDepartment extends Department { constructor() { super("Accounting and Auditing"); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }
You can extract a DepartmentInterface interface and include the generateReports() in it.
abstract class Department { constructor(public name: string) { } printName(): void { console.log("Department name: " + this.name); } } interface DepartmentInterface { generateReports(): void; } class AccountingDepartment extends Department implements DepartmentInterface { constructor() { super("Accounting and Auditing"); } printMeeting(): void { console.log("The Accounting Department meets each Monday at 10 a.m"); } generateReports(): void { console.log("Generating accounting reports..."); } }

Extract an interface

  1. Position the caret anywhere inside the class from which you want to extract an interface.

  2. Select Refactor | Extract | Interface from the main menu or Refactor | Extract Interface from the context menunu. The Extract Interface dialog opens.

  3. Specify the name of the new interface and select the checkboxes next to the class members you want to include in it.

  4. In the Destination file field, specify the location of the file where the new interface will be. By default, the field shows the path to the current file where the refactoring was invoked.

  5. Choose Extract Interface. JetBrains Rider creates a new interface and marks the source class as its implementation.

    To create an interface and replace the references to the source class with references to the interface in parameters of methods, choose Extract interface and use it where possible. JetBrains Rider shows the proposed changes in the Refactoring Preview pane of the Find tool window.

Introduce Object or Array Destructuring

Destructuring lets you easily unpack values from arrays and objects into variables. This functionality has a very concise syntax that is often used when you need to pass data in your application. See the TypeScript official website for details.

In JetBrains Rider, you can invoke destructuring using an intention action Alt+Enter. With the Replace with object/array destructuring action, the original assignment is removed. To keep the assignment, use Introduce object/array destructuring.

Replace the original assignment

  1. Position the caret at the value from an array or an object and press Alt+Enter.

  2. From the list, select Replace with object destructuring or Replace with array destructuring.

    Destructuring with intention action: Replace with array destructuring

    If some of the values from an array or an object are not used, these elements will be skipped:

    Destructuring with intention action: items skipped

Keep the original assignments

  1. Position the caret at the value from an array or an object and press Alt+Enter.

  2. From the list, select Introduce object destructuring or Introduce array destructuring.

    Destructuring with intention action: Introduce array destructuring

Generate destructuring parameters for a function

  1. Position the caret at the parameters of a function and press Alt+Enter.

  2. From the list, select Convert parameters to object.

    Destructuring with intention action: Convert parameters to object

Inline refactorings

Inline refactorings are opposite to Extract refactorings.

Example 1: Inline Variable

The Inline Variable refactoring replaces a redundant usage of a variable or a constant with its initializer. This type of refactoring is available only for block-scoped and function-scoped variables.

function Multiplication(a : number, b : number) { let c = a + b; let d = (c) * (c); return d; }
function Multiplication(a : number, b : number) { let d = ((a + b)) * ((a + b)); return d; }

Example 2: Inline Method

The Inline Method/ Inline Function refactoring results in placing the body of a method or a function into the body of its caller(s); the method/function itself is deleted.

In the example below, the body of Sum() is placed in the body of Multiplication().

function Sum(a: number, b: number) { return a + b; } function Multiplication(a: number, b: number) { let d = Sum(a, b) * Sum(a, b); return d; } var e = Multiplication(4, 6);
function Multiplication(a : number, b : number) { let d = (a + b) * (a + b); return d; } var e = Multiplication(4, 6);

Run an Inline refactoring

  • In the editor, position the caret at the symbol to be inlined and press Ctrl+Alt+N or select Refactor | Inline from the context menu or from the main menu.

Change Signature refactoring

Use the Change Signature refactoring to change the name of a function, its visibility, and return type, to add, remove, reorder, and rename parameters, and to propagate new parameters through the hierarchy of calls.

You can also add a parameter using the Introduce Parameter refactoring.

In the example below, the function eat() is renamed to feed() and a new boolean parameter isMammal is introduced.

class Animal { constructor(age: number, name: string){ } eat(food: string[]): void { } } let Max = new Animal(23, 'Max'); Max.eat(['Apple', 'Parsley']); let Daisy = new Animal(12, 'Daisy'); Daisy.eat(['Pork', 'Fish']);
class Animal { constructor(age: number, name: string){ } feed(food: string[], isMammal: boolean = true): void { } } let Max = new Animal(23, 'Max'); Max.feed(['Apple', 'Parsley'], false); let Daisy = new Animal(12, 'Daisy'); Daisy.feed(['Pork', 'Fish'], false);

Invoke Change Signature

  • In the editor, position the caret within the name of the function to refactor and press Ctrl+F6 or choose Refactor | Change Signature from the context menu or from the main menu. The Change Signature dialog opens.

Rename a function

  • In the Change Signature dialog Ctrl+F6, edit the Name field.

Change the return type of a function

  • In the Return type field, specify the type of the value that the function returns. If the field is empty, the return type is treated as void. Learn more about the return type from the TypeScript official website.

Change the visibility of a function

Manage the function parameters

  • In the Change Signature dialog Ctrl+F6, use the table of parameters and the buttons to the right of it:

    • To add a parameter, click the Add button   Alt+Insert and specify the name of the new parameter and its type. Specify the default value of the parameter or the value to be passed through function calls.

      If necessary, propagate the new parameter to the functions that call the current function.

    • To remove a parameter, click any of the cells in the corresponding row and click the Delete button   Alt+Delete.

    • To reorder the parameters, so required parameters are listed before optional ones, use the Up button   Alt+Up and the Down button   Alt+Down. Learn more about required and optional parameters from the TypeScript official website.

    • To rename a parameter, edit the Name field.

Propagate a parameter along the hierarchy of calls

  1. In the Change Signature dialog Ctrl+F6, select the parameter and click the Propagate button. The Select Methods to Propagate New Parameters dialog opens. The left-hand pane shows the hierarchy of function calls. When you select a function, the right-hand pane shows its code and the code of the function it calls in the Caller Method and Callee Method fields respectively.

  2. In the left-hand pane, select the checkboxes next to the functions where you want to propagate the parameter and click OK.

Preview the changes and complete the refactoring

  1. In the Change Signature dialog Ctrl+F6, click Preview.

  2. In the Refactoring Preview tab of the Find tool window, view the expected changes, make the necessary adjustments, and click Do Refactor when ready.

Last modified: 23 September 2021