What is the best way to confirm that my TypeScript string contains exactly two words?

Can you provide guidance on how to validate that a string contains exactly two words using TypeScript?

I'm looking to implement this validation in order to ensure that I only call the server if the name is in "first last" format.

Answer №1

The solution doesn't rely on TypeScript; it's fundamental JavaScript.

To check for a specific pattern within a string, you can utilize a regular expression like this:

function testPattern(input){
 // Check if the input contains letters (any number and any case)
 // followed by one space and then more letters (any number and any case).
 // You can easily modify the regex to account for different cases or character counts if needed.
 return /^[A-Za-z]+ [A-Za-z]+$/.test(input);
}

console.log(testPattern("Scott"));
console.log(testPattern("Scott Marcus"));
console.log(testPattern("Scott\nMarcus"));

Answer №2

When working with TypeScript, certain things cannot be directly typed, however, you can utilize type guards to specify that a parameter value must pass a specific test before being considered a valid input for a function.

Below is an example of how Scott's answer could be implemented in a "strongly typed" manner:

my-custom-types.d.ts

// A supertype for strings that have passed a RegEx test
declare type TwoWords = Branded<string, 'two-words'>

// Defines a unique primitive type as nominal types are not yet supported
// @see https://github.com/Microsoft/TypeScript/issues/202
declare type Branded<T, U> = T & { '__brand': U }

// Represents a full name in "first last" format
declare type FullName = TwoWords

my-test.ts

// Type guard that converts strings with two words to TwoWords type
function isTwoWords(input: string): input is TwoWords {
    return /^[A-Za-z]+ [A-Za-z]+$/.test(input)
}

// Function that should only receive strings with two words 
function showName(name: FullName) {
    let [first, last] = name.split(' ') // Can safely split the name
    console.log(`${last}, ${first}`)
}

let name1 = 'John'
let name2 = 'John Doe'
let name3 = 'John Doe Junior'

// Error, attempting to pass a string with unknown word count
showName(name2)

for (let name of [name1, name2, name3]) {
    if (isTwoWords(name)) {
        // No errors, TS ensures only a TwoWords type reaches this point
        showName(name)
    }
}

Answer №3

Using Regular Expressions, you can validate a string to ensure it contains two words, possibly with accents, hyphens, and apostrophes.

const allowedChars = "a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; // Reference: https://stackoverflow.com/a/1073545/188246
const isTwoWordNameRegEx = new RegExp(`^[${allowedChars}]+(['\-][${allowedChars}]+)* [${allowedChars}]+(['\-][${allowedChars}]+)*$`, "i");

isTwoWordNameRegEx.test("Sébastien Doe");         // true
isTwoWordNameRegEx.test("John Doe");              // true
isTwoWordNameRegEx.test("John Doe-Williams")      // true
isTwoWordNameRegEx.test("Scarlett O'Hara")        // true
isTwoWordNameRegEx.test("John Doe-Williams-Jane") // true
isTwoWordNameRegEx.test("John Doe-")              // false
isTwoWordNameRegEx.test("John Doe'")              // false
isTwoWordNameRegEx.test("John' Doe")              // false
isTwoWordNameRegEx.test("John Doe Williams")      // false

However, it's important to note that assumptions about names are not always accurate. Refer to Falsehoods Programmers Believe About Names for more information.

If you still wish to restrict it to two words, consider a relaxed version of the regex pattern:

const isTwoWordNameRegEx = /^\S+ \S+$/;

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

Using createStackNavigator along with createBottomTabNavigator in React Navigation version 5

I have recently started working with react native and I am using the latest version of react-navigation (v.5) in my react-native application. However, I encountered errors when trying to use createStackNavigator and createBottomTabNavigator together within ...

Tips for implementing the new useState value in your code

Using DataGrid Material UI, I am facing an issue where the selected row is not being deleted when clicking on the delete button. The problem arises from setting the ID value in the useState hook and encountering asynchronous behavior in deleting the rows. ...

Can you provide instructions for generating a simple menu bar with options utilizing webgl/three.js?

I find the documentation for the three.js 3-D viewer difficult to understand as a beginner. I am curious about the fundamental steps involved in creating a menu bar or selector with options for a 3-D viewer using three.js / WebGL. Additionally, I am inter ...

Reveal content as you scroll

I'm having trouble with the code snippet below. My goal is to utilize .cbp-fbscroller in my CSS to show a new side navigation menu on my HTML page only when scrolling down to 900px. However, as someone who is new to JavaScript, I am struggling to make ...

Losing $scope reference when incorporating a directive within the controller scope

I have a scenario in my code where I am using two directives. One directive is within the controller scope, while the other directive is not located in the html section. <div ng-show="isStore==true"> <packgroup-directive> ...

Mixed Protocol Error (HTTP/HTTPS)

I'm experiencing a mixed content error on my website, as it is using both http and https protocols. Chrome console displays the following error: Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpReques ...

Increase or decrease values in an input field using Vue3 when typing

I am looking to implement a feature where users can input numbers that will be subtracted from a fixed total of 100. However, if the user deletes the input, I want the difference to be added back to the total of 100. Despite my attempts, the subtraction wo ...

The jQuery append method is failing to interpret HTML tags

It seems like many people have encountered this issue before, but none of the suggested solutions are working for me. The problem I'm experiencing involves a method that is triggered after receiving a response from a POST request: xhr.onload= ...

Eliminate elements from an array using a specific key for filtering

My Array is called MainArray MainArray=[{ {First Name: "First Name"}, {Last Name: "Contact"}, {Last Name: "Contact"} ] I am trying to trim the key-value pair from this array like this: if (key == 'First Name') { del ...

Why isn't res.send() in Node.js sending the message?

Despite numerous attempts, I am unable to send my response message. It was working briefly, but after some code changes, it stopped functioning. Can anyone provide a solution to this challenging issue? exports.listBoth = function(req, res) { ...

What is the process for obtaining a push key in Firebase?

When a user submits data to the Firebase database, I need to handle the Key generated by that action in my own function. The challenge arises when a user fills out a form and sends data to our real-time DB. This data may include optional images, and I wan ...

Is it possible to conceal the mapbox access token during the map initialization process?

I have successfully integrated the mapbox API to create an interactive map on my website. To ensure the security of my access token, I have set up a proxy to handle the API requests externally. However, I am facing a challenge when it comes to hiding the a ...

Making Amazon Cognito function seamlessly with angular2 and typescript

Having trouble getting Cognito’s Forgot password feature to work Using: Angular2+Typescript+Ionic New to this process, followed a Quickstart guide I found here No matter what I try, keep getting errors like Cannot read property 'CognitoUser' ...

Retrieve all the keys from an array of objects that contain values in the form of arrays

Looking for an efficient way to extract all keys from an array of objects whose values are arrays, without any duplicates. I want to achieve this using pure JavaScript, without relying on libraries like lodash or underscore. Any suggestions on how to impro ...

Combining types: unable to utilize the second optional type within a for loop

I am facing an issue while looping through an array due to the union type. I am wondering what I have overlooked in the code below that is causing Visual Studio Code to not recognize the second optional type for that specific array. class Menu { // name ...

Can you explain the distinction between res.render() and ejs.render() when used in a Node.js and Express application?

Incorporating the EJS template engine into my Node.js and Express application has been seamless so far, with no issues encountered. I have been utilizing its functionality and rendering capabilities consistently. However, I have noticed that I typically u ...

Is there a different npm package that can extract paragraph data since pdf2json npm package is not working properly?

After attempting to use the pdf2json npm package to extract data from a PDF, I found that it was not extracting the data into paragraphs as desired. I have a PDF document that includes tables, paragraphs, and charts, and I am looking to extract the raw da ...

What steps do I need to take to develop a CLI application similar to ng, that can be installed globally on the system

Upon installing npm i ng -g How does the system determine the installation path? I am interested in creating an application that can be installed and executed similarly. ...

By employing timeUpdate in conjunction with currentTime

I am looking to utilize the timeUpdate and currentTime functionalities to display or hide a div at a specific time during video playback. I have been able to make it work, but it seems to be showing and hiding every second I specify. Below is the code I ...

Angular Loading Spinner Issue: ExpressionChangedAfterItHasBeenCheckedError encounted

In my Angular application, I implemented a loading-spinner component that I placed in the app component next to the router-outlet using *ngIf="isLoading". This allows me to have the loading spinner visible from every part of the application. The 'is ...