Ashish
Ashish

Reputation: 14707

how to ensure that my string have two word in typescript

How do I ensure that my string have two words in it using typescript.

The reason I need this so that I would call server only if name is in "first last" name format.

Upvotes: 0

Views: 1453

Answers (3)

David Sherret
David Sherret

Reputation: 106780

You can ensure your string has two words in it possibly containing letters with accents, multiple hyphens within, multiple apostrophes within, and separated by a space with RegEx.

const allowedChars = "a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; // 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

Now that I've mentioned this... don't do it! It's still making an assumption about how a name might be. Please read Falsehoods Programmers Believe About Names.

If you really want to restrict it to two words, then please consider a very relaxed version:

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

Upvotes: 0

cvsguimaraes
cvsguimaraes

Reputation: 13240

Things like this can't be typed with TypeScript, but you can make use of type guards to explicitly indicate that a param value needs to pass a specific test first to be a valid input to a function.

Here's what a "strongly typed" version of Scott's answer could be:

my-custom-types.d.ts

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

// Used to declare an unique primitive type, "nominal types" aren't supported yet
// @see https://github.com/Microsoft/TypeScript/issues/202
declare type Branded<T, U> = T & { '__brand': U }

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

my-test.ts

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

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

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

// Error, you can't assume this string has two words before testing it
showName(name2)

for (let name of [name1, name2, name3]) {
    if (isTwoWords(name)) {
        // No errors, TS knows that only a TwoWords type reach this line
        showName(name)
    }
}

Upvotes: 0

Scott Marcus
Scott Marcus

Reputation: 65835

The answer really isn't TypeScript dependent. It's basic JavaScript.

You can use a regular expression to perform a test on the string:

function testString(input){
 // Return whether or not there are letters (any amount and any case)
 // followed by one space and then more letters (any amount and any case).
 // Of course, if you wanted to get more specific about case or character
 // counts, adjusting the regular expression would be simple.
 return /^[A-Za-z]+ [A-Za-z]+$/.test(input);
}

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

Upvotes: 4

Related Questions