TypeScript - Determining the type of an array with multiple data types

When dealing with an array of union, checking the typeof value can be done this way:

//case 1
function something1(a1: Array<number | string | boolean>)
{
    for (const v of a1)
        if (typeof v === "number")
            v;  //v is number
        else if (typeof v === "boolean")
            v;  //v is boolean
        else
            v;  //v is string
}

A similar approach can be taken with a union of arrays:

//case 2
function something2(a1: Array<number> | Array<string> | Array<boolean>)
{
    for (const v of a1)
        if (typeof v === "number")
            v;  //v is number
        else if (typeof v === "boolean")
            v;  //v is boolean
        else
            v;  //v is string
}

However, the goal is to avoid type checking inside the loop:

//case 3
function something3(a1: Array<number> | Array<string> | Array<boolean>)
{
    if (a1.length === 0)
        return;
    if (typeof a1[0] === "number")
        a1;  //should be number[]!!     but it is  number[] | string[] | boolean[]
    if (typeof a1[0] === "boolean")
        a1;  //should be boolean[]!!    but it is  number[] | string[] | boolean[]
    if (typeof a1[0] === "string")
        a1;  //should be string[]!!     but it is  number[] | string[] | boolean[]
}

However, a1 is not recognized as number[], string[], or boolean[].

It would make sense since all items in the array are of the same type. Is there a way to achieve this?

The TypeScript version being used is beta 2.0.

Answer №1

Utilizing type guards:

function checkArrayType(arr: Array<number> | Array<string> | Array<boolean>) {
    if (arr.length === 0)
        return;
    if (isNumberArray(arr))
        arr[0].toExponential();
    if (isBooleanArray(arr))
        arr[0].valueOf();
    if (isStringArray(arr))
        arr[0].indexOf('abc');
}

function isNumberArray(arr: number[] | string[] | boolean[]) : arr is number[] {
    return arr.length > 0 && typeof arr[0] === 'number';
}

function isBooleanArray(arr: number[] | string[] | boolean[]) : arr is boolean[] {
    return arr.length > 0 && typeof arr[0] === 'boolean';
}

function isStringArray(arr: number[] | string[] | boolean[]) : arr is string[] {
    return arr.length > 0 && typeof arr[0] === 'string';
}

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

Converting JSON data into an array of a particular type in Angular

My current challenge involves converting JSON data into an array of Recipe objects. Here is the response retrieved from the API: { "criteria": { "requirePictures": true, "q": null, "allowedIngredient": null, "excluded ...

Aligning the React Navigation header component's bottom shadow/border width with the bottom tabs border-top width

Currently, I am working on achieving a uniform width for the top border of the React Navigation bottom tabs to match that of the top header. Despite my efforts, I am unable to achieve the exact width and I am uncertain whether it is due to the width or sha ...

When executing the project, the information fails to appear on the screen

I am new to angular and I have been trying to use the http module to fetch data from my backend. In my user.component.html file, I have the following code: <tr *ngFor="let item of transporter.liste"> <td>{{item.name}}</td> ...

Error Encountered: Monorepo Shared Package Not Detected in Docker-Compose Execution

In my development setup, I have organized a monorepo using lerna and yarn workspaces. All code is written in typescript and then compiled into javascript. However, I encountered an issue with sharing packages when running the monorepo with docker-compose. ...

Exploring the Power of Typescript and Graphql Fragments

Utilizing codegen, I automatically generate TypeScript types and employ Apollo client to submit requests to the server. However, when I execute code generation for the given example, TypeScript fails to recognize that the people object contains firstName ...

The value of form.formGroup is not equivalent to the output of console.log(form)

Having an issue here. When I send a Form to a component, If I use console.log(form), it displays the object correctly. However, when I check the form in the console, the form.formGroup.value looks fine (e.g. {MOBILE0: 'xxx', PHONE0: 'xxx&ap ...

Apologies: the declaration file for the VueJS application module could not be located

Hey there! I'm currently working on a VueJS application using NuxtJS. Recently, I added an image cropping library called vue-croppie to my project. Following the documentation, I imported the Vue component in the code snippet below: import VueCroppie ...

A guide on converting array values to objects in AngularJS HTML

Here is my collection of objects: MyCart = { cartID: "cart101", listProducts : [ {pid:101, pname:"apple", price: 200, qty:3}, {pid:102, pname:"banana", price: 100, qty:12} ] } I have incorporated a form in ...

Switch back and forth between two pages within the same tab on an Ionic 3 app depending on the user's login information

I am seeking a way to switch between two profile pages using the profile tab based on whether the user is a student or tutor in an ionic 3 application. ...

Experience feelings of bewilderment when encountering TypeScript and Angular as you navigate through the

Exploring Angular and TypeScript for an Ionic project, I am working on a simple functionality. A button click changes the text displayed, followed by another change after a short delay. I'm facing confusion around why "this.text" does not work as exp ...

Using Typescript to set the image source from a pipe

I've been working on creating a custom pipe similar to the code below: @Pipe({ name: 'imagePipe' }) @Injectable() export class ImagePipe { constructor(public someService: SomeService, public storage: Storage) { } transform(value: ...

An issue has been encountered: No NgModule metadata was discovered for 'AppModule' in the ngx-rocket Metronic theme

Task List [ ] Initialize [x] Build [x] Serve [ ] Test [ ] End-to-End test [ ] Generate [ ] Add [ ] Update [ ] Lint [ ] Internationalization [ ] Run [ ] Configure [ ] Help [ ] Version [ ] Documentation Is this a regression? This issue started occurring ...

Analyzing the type of object properties from a different perspective

I am new to TypeScript and have encountered many similar questions. I was able to find a solution, but I'm not sure if it's the most efficient one. When constructing the target object as {obj: someObject, prop: "objectPropName"}, I pas ...

The variable being declared at the class level inside a function within the same class is not recognized

Seeking guidance on the code snippet I'm currently studying. I am implementing a TypeScript 1.8.10 compiler along with EM5: module myAmazingModule{ 'use strict'; export interface INavigateService { links: string[], ...

Difficulty with Ionic: unable to compile for android

I am currently working on an Ionic 3.4 project and trying to build it for Android testing. Following the installation of Android Studio, the Android SDK, and Java 8, I proceeded with the command: ionic cordova platform add android However, when I atte ...

Encountering the error message `TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"` with `ts-node` when the type is specified as module

After configuring absolute paths in my Express project and changing the type to module for using import, I encountered an error: TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" Below is the content of my tsconfig.json { &q ...

Observing changes in a parent component variable with Angular

One feature of my form is that it consists of a parent component and a child component. To disable a button within the form, I utilize a function called isDatasetFilesValid() which checks a specific variable (datasetList[i].fileValid). This variable is mo ...

"Transferring a C# dictionary into a TypeScript Map: A step-by-step

What is the correct way to pass a C# dictionary into a TypeScript Map? [HttpGet("reportsUsage")] public IActionResult GetReportsUsage() { //var reportsUsage = _statService.GetReportsUsage(); IDictionary<int, int> te ...

The absence of typings.json in Typescript is creating an issue

As of now, I am encountering the following error during compilation: typings.json is missing In my existing packages.json, I have included the following dependency: "devDependencies": { "typescript": "^2.6.1", ... } Do you have any suggestion ...

What is the best way to attach an EventListener to all DOM elements with a particular class?

Within my DOM, I have dynamically created spans that all have the class "foo". Utilizing TypeScript, I aim to attach an onClick event to each of these spans post-creation. Here is my current approach: var foos = document.body.querySelectorAll(".foo"); f ...