Validating input parameters with a Typescript union type

Looking to determine if a string contains a specific prefix from a union type:

type Prefix = "ABC" | "DEF" | "GHI" ...;
const hasPrefix = (str: string): boolean => {
   // Goal is to compare the first 3 characters of the string
   // With the prefixes in the Prefix type
   // For example:
     // if (str.substr(0, 3) === Prefix)
}

Answer №1

The ability to dissect a union type is not currently available in the latest version of TypeScript. A recommended solution for this issue involves utilizing enums, as demonstrated below:

enum Prefixes {
    "ABC",
    "DEF",
    "GHI"
}

const hasPrefix = (str: string): boolean => Prefixes[str.substr(0, 3) as any] !== "undefined";

console.log(hasPrefix("123")); // false
console.log(hasPrefix("ABC")); // true
console.log(hasPrefix("DEF")); // true
console.log(hasPrefix("GHI")); // true
console.log(hasPrefix("GHII"));// true

const data = "ABC123";         // ABC123

console.log(hasPrefix(data));  // true
console.log(data);             // still ABC123

Here's a TypeScript playground link to view and test the code.


Based on your query, it seems that you are interested in dynamically checking prefixes, as indicated by the characters (?). To address this, a solution incorporating a Set data structure was devised. See example code snippet below:

// Set data structure ensures uniqueness
type Prefix = string;
const prefixes: Set<Prefix> = new Set();

prefixes.add("ABC");
prefixes.add("ABC");
prefixes.add("DEF");
prefixes.add("GHI");

// Double addition of ABC does not affect uniqueness
console.log(prefixes);

// Typeguard function
const hasPrefix = (str: any): str is Prefix => typeof str === "string" ? prefixes.has(str.substr(0, 3)): false;

console.log(hasPrefix(100));   // false
console.log(hasPrefix(0));     // false
console.log(hasPrefix(false)); // false
console.log(hasPrefix(true));  // false
console.log(hasPrefix(""));    // false
console.log(hasPrefix("123")); // false
console.log(hasPrefix("ABC")); // true
console.log(hasPrefix("DEF")); // true
console.log(hasPrefix("GHI")); // true
console.log(hasPrefix("GHII"));// true

const data = "ABC123";         // ABC123

if (hasPrefix(data)) {
    console.log(hasPrefix(data));  // true
    console.log(data);             // still ABC123
}

View the code playground here.

Answer №2

It seems that, at the current moment, achieving this solely with native Typescript types may not be feasible. Here is a link to an issue on GitHub regarding this topic, and for further insight, you can refer to: How can I define a type in Typescript that matches a regex pattern?

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

Adjusting the height of content in Angular Material 2 md-tab

I've recently started working with angular material and I'm facing an issue while trying to implement md-tab into my application. The problem is that I can't seem to style my tab content to take up the remaining height of the screen. Could s ...

Leveraging the spread operator in cases where the value is null

Is there a more elegant solution for handling null values in the spread operator without using if-else statements? In this specific case, I only want to spread assignedStudents if it is not undefined. When attempting to do this without using if-else, I e ...

What is the best way to use multiple encoding types when sending data via a POST method in Node.js?

My current challenge involves sending a combination of name and description text data alongside a video file. Unfortunately, I've encountered an issue where I can only send either the video or the text, but not both simultaneously. Below is the code ...

How can I upload a folder with subfolders and keep the structure intact?

I'm working on a form that allows me to upload a folder containing both files and subfolders with more files inside. I managed to upload the folder successfully, but when I check my directory, all the files are in one folder without the subfolders. My ...

One-click process succeeds where two clicks fail

The code below is intended to go through a two-click process as follows: First click on .imagenes decreases opacity and makes .logo visible. Second click on .imagenes returns the opacity to 1 and hides .logo again. However, during this cycle of two ...

Firefox is unable to display SWF files

My code snippet: <div id="sw" style="cursor:pointer" > <object id="swfobj" type="application/x-shockwave-flash"> </object> The JavaScript part: function openfile(filePath) { $("#swfobj").attr("data", filePath); $("#sw ...

Achieving success in element-ui vuejs involves validating the state with the :error parameter

I recently developed an app using Laravel, Vuejs, and Element-ui. Within my form, I have utilized the "error" property to indicate that Laravel validation is in place. <el-form-item label="First Name" prop="firstname" :error="registerForm.errors.get(&a ...

Having trouble mocking Node fs Modules using Sinon

I am facing an issue with mocking the promises methods of the node fs module in my code. When my appData.ts file is executed, it calls the actual fs.promises.mkdir method instead of the mock function defined in \__tests__/appData.test.js. I suspect ...

An issue occurred while attempting to retrieve Firebase data using an HTTP GET request

When trying to retrieve my data from firestore using an HTTP get request, I encountered an error. It might be helpful if my data in firestore was stored in JSON format. I'm not sure if this is feasible. <!DOCTYPE html> <html lang="en"> ...

What could be causing the issue with dayjs dynamic importing in TypeScript?

Currently, I am developing a web screen within a .NET application and facing an issue with sending datetime preferences from the system to the web screen using CefSharp settings. AcceptLanguageList = CultureInfo.CurrentUICulture.Name In my TypeScript code ...

Issue with Jest mock function failing to trigger axios instance function causing it to return undefined

I initially found a solution on this StackOverflow thread However, I wanted to add my own helper function that generates a fresh Axios instance with the user's authentication token. Here is what I came up with: import axios from "axios"; c ...

Node.js/TypeScript implementation of the Repository design pattern where the ID is automatically assigned by the database

Implementing the repository pattern in Node.js and Typescript has been a challenging yet rewarding experience for me. One roadblock I'm facing is defining the create function, responsible for adding a new row to my database table. The interface for ...

In a peculiar occurrence, the behavior of array.splice is exhibiting unusual characteristics within an

Be sure to take a look at this plunkr for reference: http://plnkr.co/edit/FQ7m6HPGRrJ80bYpH8JB?p=preview I'm encountering an issue where, after adding an element and then deleting it from the array using the splice method, everything becomes disorg ...

How to check Internet upload speed in Angular without using a backend server?

I need help uploading a file to a folder within my Angular app's directory while it is running on localhost. I have been unable to find a solution that doesn't involve using backend technologies. For instance, I simply want to upload an image fi ...

What could be causing the malfunction of useEffect() in my script?

const [isOpen, setIsOpen] = useState(false); useEffect(() => { if (!token) { return <Navigate to="/auth/login"/> } getMe(token) }, [token, getMe]) return ( <RootStyle> <DashboardNavbar onOpenSi ...

As you scroll, a box blocks off half of the screen

Hey everyone, I could really use your assistance! I'm working on developing a javascript code and here is the idea - if anyone can contribute to it. It's like a social media platform where users enter the site and the is_user_logged_in parameter ...

populate a data list with information sourced in Angular 8

I am looking to populate this model oldDataSource: Array<any> = []; with the values from the datasource. This is the code I have tried: ngOnInit(): void { this.dataSourceInit(); } dataSourceInit(): void { this.dataSource = new DefaultScore ...

Dynamic backdrop featuring engaging content

I am currently working on a WordPress website that features a dynamic background. While I have successfully implemented movement to the background, the content on the site remains static and unaffected by scrolling. The background does not move alongside t ...

How to target a form in jQuery without using a class selector

Within my project, there exists a form, <form id="form3" name="form3"> <input type="text" id="number" name="number" value="" >Number</input> <button type="button" onclick="submit();">Submit</button> </form> When at ...

An element generated through JavaScript fails to display on the webpage

As I navigate through the code with a foreach() loop, my goal is to generate a new div every time a firebase document containing the user's email is encountered. The script involves a blend of react js and javascript as I am still learning the ropes o ...