Do not verify the accuracy of arguments within the function itself

Today, I came across a function in our codebase that appears to have a logical flaw. The function is written in TypeScript and looks like this:

const getUserInitials = (user: IUser | null) => {
   if (!user) { return ""; }
   
   return (user.FirstName.charAt(0) + user.LastName.charAt(0)).toUpperCase();
}

After some analysis, it seems to me that allowing the function to accept incorrect argument types and then trying to handle them internally by returning an empty string is not ideal. Instead, I believe the function should only accept arguments of type IUser, with any necessary argument checking done before invoking the function.

This raises the question of whether it should be considered a best practice to always check for argument correctness before calling a function? While there are cases where internal checks are necessary, such as ensuring an integer falls within a certain range, in situations like the one presented here, it may result in violating the function's contract.

In fact, I suggest renaming the function to

getInitials(user: IUser) => {...}

as the word "user" in the function name becomes redundant when the argument itself is clearly specified.

  1. Do you agree that validating arguments before function invocation is crucial in preventing contract violations?

  2. Are there instances in statically typed languages where checking argument correctness internally is acceptable?

  3. Is my observation about redundancy in function naming accurate?

Thank you for your insights.

Answer №1

  1. Your understanding is partially accurate:

    a: It's always beneficial to validate the arguments passed to your function and plan for exceptional scenarios in its design. This holds particularly true in languages like Typescript, which can interact with Javascript, known for being untyped. While it may be advisable that no one should call this function without a valid user, it's important to acknowledge that there might still be instances where they do.

    b: If you can derive meaning from a null argument, it's sensible to handle it and return a suitable default value. However, issuing an empty string as output in this scenario is deemed inappropriate. It would be more prudent to raise an error instead.

    c: If assigning a reasonable default value is not feasible, then the method signature should explicitly disallow null arguments. Nonetheless, you can still include checks for them and throw a more informative error rather than relying on default behavior. Regrettably, some developers configure eslint in a manner that triggers complaints about such validations, leading to the common practice of appending '| null' to method signatures.

  2. Relying solely on static typing is insufficient. In cases where a language ensures that a function cannot be ambiguously called with incorrect argument types, manual type checking becomes unnecessary. Unfortunately, Typescript does not offer this level of enforcement.

  3. Absolutely incorrect. Within Typescript, the arguments of a method are not considered part of its signature. For instance, 'getInitials(user: User)' is identical to 'getInitials(firstName: string, lastName: string)'. Once a function named 'getInitials' is declared, no other function with the same name can coexist within the same scope. Avoid assuming that your implementation warrants an undistinguished title.

Answer №2

Question 1: It is advisable to always validate arguments before passing them to a function.

Question 3: Personally, I believe it is better not to use vague names like GetInitials in functions. For example, if you call the function without knowing its purpose, confusion may arise.

(This issue can be avoided in object-oriented programming by having a structure like User.GetInitials(), where the user is already incorporated in the name.)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Generic Type for Promise in Typescript

I have a sample Promise function that is shown below. When successful, it returns a number, and when unsuccessful, it returns a string. The compiler is asking me to specify some kind of generic type for the promise. In this scenario, what type should I s ...

Angular 2 Service's filtering functionality can be enhanced with an Array parameter

I developed a function to retrieve filtered results from a JSON dataset. getItem(id: string): Observable<any[]> { return this.http.get('path/to/my.json') .map((response) => { let results: any = response.json( ...

Tips for adding multiple conditions in an *ngIf statement within Angular 6

Running into navigation issues, <div *ngIf = ("path == '/login'" && "path == '/home'") class="tabs-header-nav"> <a routerLink="/login" class="nav-link active">login</a> <a routerLink="/bb" class="nav-link"& ...

Is it better to convert fields extracted from a JSON string to Date objects or moment.js instances when using Angular and moment.js together?

When working on editing a user profile, the API call returns the following data structure: export class User { username: string; email: string; creationTime: Date; birthDate: Date; } For validating and manipulating the birthDate val ...

Issue: The TypeError reported is due to the absence of any definition for "_co.category.category_type"

I have two models: CategoryTypes and Categories. Each category type contains multiple categories. These are my two models. Categories Model import { Categories } from '../../categories/Mode/Categories' export class CategoryType { _id: strin ...

What is the best way to retrieve the query results from Firestore?

After researching extensively, I have yet to find a solution to my issue with returning query results. Despite successfully executing the query, my client fails to receive the desired response. export const myFunction = functions.https.onCall((data, conte ...

Out of the blue, I encountered an issue while trying to install Express in node.js using Types

Encountered a failure while attempting to install Express with node.js in Typescript. Received the following warning: https://i.sstatic.net/XcrGX.png Performed npm initialization, started index.js, created tsconfig.json, and installed ts-node. The comman ...

Cancel the starting path in Angular 9 and initiate a redirection

I am attempting to change the initial path such as localhost:4200/ so that it displays an error view instead of the home page. I want the home page to only be accessible if you navigate to something like localhost:4200/tag1/tag2. I need to be able to capt ...

How can I ensure that a TypeScript function with the types A or B only returns type B without encountering any type errors?

Consider the following function as an example: interface InputTime { month : number, year : number } const getMonthAndYear = (time: InputTime | Date): InputTime => { if(isValid(time)) { // time is a date object return ...

Import Firebase User in Typescript v8 definition

In the previous versions of Firebase, I used to import the Typescript definition of the User like this: import {User} from 'firebase'; However, with the introduction of v8, this import no longer works and gives the following error message: Mod ...

Disable and grey out the button while waiting for the Observable to broadcast successfully

component.html <button mat-raised-button color="primary" type="submit"> <mat-icon>account_box</mat-icon> <span *ngIf="!loading">&nbsp;&nbsp;&nbsp;Register</span> <span * ...

Mastering GraphQL querying in React using TypeScript

After successfully setting up a graphql and being able to use it in Postmen, here is how it looks: query listByName($name: String!) { listByName(name: $name) { id name sortOrder } } My variable is defined as {"name&quo ...

Tips for retrieving a concrete subclass instance rather than the abstract class type

Within a subclass called WorldDetail, I have defined objects representing page names and concrete class names within the pages property. In the abstract class, I have implemented a method named getPage to retrieve an instance of the concrete class based o ...

Tips for using Luxon to format timestamps

Recently, I decided to make the switch from using moment.js to Luxon for handling dates and times. With moment.js, I was able to convert a Date() object to timestamp format like this: ....moment() .subtract(2, 'hours') .utc() .f ...

How can angular/typescript be used to convert a percentage value, such as 75.8%, into a number like 75.8?

I have obtained a value (for example, "75.8%") as a string from an API and I need to convert it to a number in order to apply conditions. For instance: <div class="container" [ngClass]="{ 'pos' : value > 0, ...

Tips on sending an argument via a TypeScript-defined custom hook in React

When attempting to pass a string value in a custom hook call to the hook file itself, an error is encountered. The specific issue is TS2345: Argument of type 'string' is not assignable to parameter of type '{ string: any; }', even with ...

Angular 13: Masking User Input with Reactive Form Controls

Looking to incorporate a phone number input field with formatting in a reactive form. The desired format is (123) 456-7890. For reference, check out this example link: https://stackblitz.com/edit/angular13-reactive-form-validation-y1qwmf?file=src/app/app. ...

What goes on behind the scenes of Angular interpolation with scripts?

I set up a variable called test = '<script>alert()</script>'. I then inserted this variable into an Angular component using interpolation like so: <div>{{ this.test }}</div>. However, instead of rendering properly, it just ...

What obstacles are keeping Stryker from participating in the TypeScript Express project?

Check out my public repository on GitHub. It's a straightforward ExpressJS NodeJs project written in TypeScript and utilizes Jest for unit testing. When I execute npx stryker run --fileLogLevel trace --logLevel debug, I encounter the following output ...

Exploring the TypeScript Type System: Challenges with Arrays Generated and Constant Assertions

I am currently grappling with a core comprehension issue regarding TypeScript, which is highlighted in the code snippet below. I am seeking clarification on why a generated array does not function as expected and if there is a potential solution to this pr ...