Last active
August 9, 2018 18:33
-
-
Save mrhampson/46b2ac01287f93a1531efcb2e12dce0c to your computer and use it in GitHub Desktop.
Typescript overuse of default parameter issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| I created this gist to point out something I consider a bad practice that I've seen in typescript code: | |
| that is overuse of default parameters. The problem with overusing default parameters is that the default behavior | |
| of the function without args is completely implicit and requires the developer to reference the function definition and | |
| memorize whenever they are looking through the code. | |
| In the examples below I took some of our existing code that had such a function retrieveData where its behavior | |
| was hidden behind default parameters. I refactored it by using functions that are named something descriptive that | |
| then call retrieveData with the appropriate parameters. By providing a function with a descriptive name rather than | |
| letting parameter default it is much clearer what the code is doing when you are far away from the retrieveData | |
| function definition. | |
| To be clear, I'm not suggesting default parameters should never be used. In certain situations they can make things | |
| clearer and save repeated code. | |
| */ | |
| /*************************************************************** | |
| * Before refactor | |
| ***************************************************************/ | |
| private retrieveData(activeOnly = true, inactiveOnly = false) { | |
| // gets data | |
| } | |
| // Later on | |
| // What is this doing? No idea without having memorize the function definition further up. | |
| // This boolean condition is also copy/pasted multiple times | |
| this.retrieveData(this.$scope.activeTabsAlerts.id === LaAlerting.ACTIVE_TAB.id); | |
| // Later on | |
| // Same problem: no idea what this means. Entirely implicit and relys on the developer memorizing the definition | |
| this.retrieveData(true) | |
| /*************************************************************** | |
| * After refactor | |
| ***************************************************************/ | |
| // The functions below replace the original function with default parameters | |
| // By putting the logic for which tab gets what data in this function rather than copy/pasteing a conditional statement | |
| // that evaluates to the activeOnly paramter we avoid copy/paste code of the conditional and make the logic clearer | |
| // and less prone to mistakes | |
| private getDataForTabId(tabId) { | |
| if (tabId === LaAlerting.ACTIVE_TAB.id) { | |
| this.retrieveOnlyActiveAlerts(); | |
| } | |
| else { | |
| this.retrieveAlerts(); | |
| } | |
| } | |
| private retrieveOnlyActiveAlerts() { | |
| return this.retrieveData(true, false); | |
| } | |
| private retrieveAlerts() { | |
| return this.retrieveData(false, false); | |
| } | |
| private retrieveData(activeOnly:boolean, inactiveOnly:boolean) { | |
| // gets data | |
| } | |
| // Later on in code | |
| // No repeated boolean logic | |
| this.getDataForTabId(this.$scope.activeTabsAlerts.id); | |
| // Later on in code | |
| // Code is self describing and says what it does | |
| this.retrieveOnlyActiveAlerts(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment