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, PyCharm lets you move TypeScript top-level symbols. The Move Symbol Refactoring works for classes, functions, and variables in ES6 modules.
To move a class, a function, or a variable
Select the symbol to move.
Press F6 or choose Refactor | Move on the main menu or on the context menu of the selection. The Move Module Members dialog opens.
Specify the destination file and select the members to move.
By default, PyCharm 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.
abstractclassDepartment{constructor(publicname: string){}printName():void{console.log("Department name: "+this.name);}}interfaceReportingDepartment{generateReports():void}classAccountingDepartmentextendsDepartmentimplementsReportingDepartment{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.
abstractclassDepartment{constructor(publicname: string){}printName():void{console.log("Department name: "+this.name);}printMeeting():void{console.log("The Accounting Department meets each Monday at 10 a.m");}}interfaceReportingDepartment{generateReports():void}classAccountingDepartmentextendsDepartmentimplementsReportingDepartment{constructor(){super("Accounting and Auditing");}generateReports():void{console.log("Generating accounting reports...");}}
Example 2: Moving a class method to the interface In this example, the PrintMeeting() method is copied from the AccountingDepartment class to the ReportingDepartment interface.
abstractclassDepartment{constructor(publicname: string){}printName():void{console.log("Department name: "+this.name);}}interfaceReportingDepartment{generateReports():voidprintMeeting():void}classAccountingDepartmentextendsDepartmentimplementsReportingDepartment{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...");}}
To move the methods of a class to a superclass or the interface
Place the cursor anywhere inside the class from which you want to pull the members up.
Choose Refactor | Pull Members Up on the main menu or on the context menu. The Pull Members Up dialog opens.
From the drop-down list, choose the superclass or the interface where you want to move the methods.
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, functions, variables, and parameters. PyCharm changes the name of the symbol in its declaration and by default all its usages in the current project.
To rename a function, a class, or a variable
In the editor, select the symbol to rename and press Shift+F6 or choose Refactor | Rename on the context menu or on the main menu.
In the Rename dialog that opens, type the new name of the symbol.
Optionally:
Select the Search in comments and strings and Search for text occurrences checkboxes to rename the usages of the function or the class in comments, string literals, documentation, HTML, and other files included in the project.
Select the Search JavaScript References checkbox to rename the usages of the function or the class in generated JavaScript code.
Select the parameter in the editor and press Shift+F6 or choose Refactor | Rename on the context menu or on the main menu.
In the text box with red canvas around the selected parameter, type the new parameter name.
Press Enter to run the refactoring.
Keeping the names of classes and containing files in compliance
When you rename a class, PyCharm also suggests renaming the file if it has the same name. If you accept the suggestion, PyCharm 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 file name is determined by the style chosen from the the Filename convention list on the Code Style: JavaScript page.
To keep the name of a file in compliance with the name of the corresponding class
Place the cursor at the name of the class and press Alt+Enter.
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>.
Extract refactorings
PyCharm 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 | Extract | <target>. You can select an entire expression or place the cursor anywhere inside it and PyCharm will help you with the selection.
Extract Parameter
Use the Extract Parameter refactoring to replace an expression in the calls of a function with a parameter. PyCharm 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().
With the Extract 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.
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.
In the editor, place the cursor within the expression that you want to convert into a parameter and press Ctrl+Alt+P or choose Refactor | Extract | Parameter on the context menu or on the main menu.
If several expressions are detected in the current cursor location, select the required one in the Expressions list.
If more than one occurrence of the selected expression is found, choose Replace this occurrence only or Replace all occurrences in the Multiple occurrences found pop-up menu. Finally, the pop-up window for configuring the refactoring appears.
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.
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, PyCharm 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>.
Accept one of the suggested parameter names by double-clicking it in the pop-up list or specify a custom name in the text box with red canvas. Press Enter when ready.
Choosing the refactoring mode
You can extract a parameter right in the editor (in the in-place mode) as described above or use the Extract Parameter dialog. These two approaches are rather similar, the difference is as follows:
Previewing the results of the refactoring. In the dialog box, 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 box, PyCharm suggests the default parameter value in the Value field where you can accept the suggestion or specify another value. In the in-place mode, PyCharm 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.
In the editor, select the expression to convert into a variable and press Ctrl+Alt+V or choose Refactor | Extract | Variable on the context menu or on the main menu.
If several expressions are detected in the current cursor location, select the required one in the Expressions list.
If more than one occurrence of the selected expression is found, choose Replace this occurrence only or Replace all occurrences in the Multiple occurrences found pop-up menu. Finally, the pop-up window for configuring the refactoring appears.
In the pop-up menu, choose the statement to use in the declaration of the new variable:
Choose var to introduce a function-scoped variable. This variable can be declared in the enclosing function or outside any function.
Accept one of the suggested variable names by double-clicking it in the pop-up list or specify a custom name in the text box. 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 Extract Variable dialog. By default, PyCharm runs the Extract Variable refactoring in the in-place mode. To use the Extract Variable dialog box, In the Settings/Preferences dialog (Ctrl+Alt+S), click Editor | General. On the General page that opens, clear the Enable in-place mode checkbox in the Refactorings area.
Extract Field
The Extract Field refactoring declares a new field and initializes it with the selected expression. The original expression is replaced with the usage of the field.
In all the three examples below, the same field, _calcArea is extracted. The examples illustrate three different ways to initialize the extracted field.
Example 1: The extracted field _calcAreais initialized in the enclosing method get Area()
In the editor, select the expression to convert into a field and press Ctrl+Alt+F or choose Refactor | Extract | Field on the context menu or on the main menu.
Choose the field visibility, the available options are Public, Private, and Protected. Learn about field visibility modifiers from the TypeScript Official website
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, PyCharm 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 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.
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.
In the editor, select a code fragment to convert into a function and press Ctrl+Alt+M or choose Refactor | Extract | Method on the context menu or on the main menu.
If the selected expression is inside another function, choose the destination scope from the pop-up list:
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.
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.
To open the Extract Function dialog by default
In the Settings/Preferences dialog (Ctrl+Alt+S), click Editor | General. On the General page that opens, clear the Enable in-place mode checkbox 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.
Suppose you have the following fragment of code with a { z: number } type declaration:
In the editor, place the cursor within the expression that you want to replace with a type alias and choose Refactor | Extract | Type Alias on the context menu or on the main menu.
If several expressions are detected in the current cursor location, select the required one in the Expressions list.
If more than one occurrence of the selected expression is found, choose Replace this occurrence only or Replace all occurrences in the Multiple occurrences found pop-up menu.
In the text box, type the name of the type alias and press Enter when ready.
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.
classAccountingDepartment{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.
classDepartment{name: string;printName():void{console.log("Department name: "+this.name);}}classAccountingDepartmentextendsDepartment{printMeeting():void{console.log("The Accounting Department meets each Monday at 10 a.m");}generateReports():void{console.log("Generating accounting reports...");}}
To extract a superclass
Place the cursor anywhere inside the class from which you want to extract a superclass.
Choose Refactor | Extract | Superclass on the main menu or on the context menu. The Extract Superclass dialog opens.
Specify the name of the new superclass and select the checkboxes next to the class members you want to include in it.
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.
Choose Extract Superclass. PyCharm 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. PyCharm 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.
abstractclassDepartment{constructor(publicname: string){}printName():void{console.log("Department name: "+this.name);}}classAccountingDepartmentextendsDepartment{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.
abstractclassDepartment{constructor(publicname: string){}printName():void{console.log("Department name: "+this.name);}}interfaceDepartmentInterface{generateReports():void;}classAccountingDepartmentextendsDepartmentimplementsDepartmentInterface{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...");}}
To extract an interface
Place the cursor anywhere inside the class from which you want to extract an interface.
Choose Refactor | Extract | Interface on the main menu or on the context menu. The Extract Interface dialog opens.
Specify the name of the new interface and select the checkboxes next to the class members you want to include in it.
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.
Choose Extract Interface. PyCharm 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. PyCharm shows the proposed changes in the Refactoring Preview pane of the Find tool window. Note that if an instance references a method or a field that is not defined in the interface, PyCharm will not suggest replacing it.
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.
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().
In the editor, place the cursor at the symbol to be inlined and press Ctrl+Alt+N or choose Refactor | Inline on the context menu or on the main menu.
In the Inline dialog box that corresponds to the selected symbol, confirm the inline refactoring.
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.
In the example below, the function eat() is renamed to feed() and a new boolean parameter isMammal is introduced.
In the editor, place the cursor within the name of the function to refactor and press Ctrl+F6 or choose Refactor | Change Signature on the context menu or on the main menu. The Change Signature dialog opens.
To rename a function
In the Change Signature dialog (Ctrl+F6), edit the Name field.
To 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.
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 (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.
To remove a parameter, click any of the cells in the corresponding row and click (Alt+Delete).
To reorder the parameters, so required parameters are listed before optional ones, use (Alt+Up) and (Alt+Down). Learn more about required and optional parameters from the TypeScript Official website.
To rename a parameter, edit the Name field.
To propagate a parameter along the hierarchy of calls
In the Change Signature dialog (Ctrl+F6), select the parameter and click . 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.
In the left-hand pane, select the checkboxes next to the functions where you want to propagate the parameter and click OK.
To preview the changes and complete the refactoring
In the Change Signature dialog (Ctrl+F6), click Preview.