Error with Array type encountered in Typescript's find method

I am encountering an issue with code that looks like this:

type X = {
  test: number;
  x: number;
}[];

type Y = {
  test: number;
  y: number;
}[];

type Z = {
  test: number;
  z: number;
}[];

export const testFunc = (arg: X | Y | Z) => {
  return arg.find((e: (X | Y | Z)[number]) => e.test === 1);
  //         ~~~~
  //      Error 2349
};

When using VSCode, the find method is highlighted with an error message:

This expression is not callable.
  Each member of the union type '{ <S extends { test: number; x: number; }>(predicate: (this: void, value: { test: number; x: number; }, index: number, obj: { test: number; x: number; }[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: { ...; }, index: number, obj: { ...; }[]) => unknown, thisArg?: any): { ...; } | undefined; } |...' has signatures, but none of those signatures are compatible with each other. (2349)

What could be causing this issue?

Click here for TypeScript Playground code

Answer №1

TS is searching for a common ground among 3 conflicting signatures - solution.

To resolve this, you can establish a foundational interface with the solution attribute and then extend the types of the entity from the Base interface. This enables the use of generics, allowing you to specify that the solution function accepts any object that extends Base (TS playground):

interface Base {
  solution: number
}

interface A extends Base {
  a: number
}
interface B extends Base {
  b: number
}
interface C extends Base {
  c: number
}

export const solution = <T extends Base>(arg: T[]) => {
  return arg.find((e: T) => e.solution === 1)
}

Answer №2

Aside from the signature mismatch, there is a minor error in the code line

return arg.find((e: (A | B | C)[number]) => e.test === 1)

The variable e should not be A|B|C because A,B,C are array types.

I believe you need something like this:

type A = {
  test: number
  a: number
}
type B = {
  test: number
  b: number
}
type C = {
  test: number
  c: number
}

export const test = (arg: (A|B|C)[]) => {
  return arg.find((e: (A | B | C)) => e.test === 1)
}

The issue with the signature arises in the return type of find(). The return type of T[].find() is T|undefined. In this case, it should be (A|B|C)|undefined. Hence, using (A|B|C)[] resolves the problem and sets the return type as (A|B|C)|undefined. Try this on Playground

Answer №3

To enhance the representation of object members within arrays, adjust your types accordingly. By refining the function signature to specify that the argument is an array containing a union of all object types, TypeScript will effortlessly deduce that the test property is shared among all types in the union:

TS Playground

type A = {
  test: number;
  a: number;
};

type B = {
  test: number;
  b: number;
};

type C = {
  test: number;
  c: number;
};

export const test = (array: (A | B | C)[]) => {
  return array.find(element => element.test === 1);
};

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

In AngularJS, the use of the '+' operator is causing concatenation instead of addition

Looking for assistance with my TypeScript code where I've created a basic calculator. Everything is working as expected except for addition, which seems to be concatenating the numbers instead of adding them together. HTML CODE : <input type="tex ...

"Exploring Angular 9: A guide to retrieving form data with an array of objects [Revised as of July 29th, 2020

I am encountering an issue with my Angular 9 form code. I am getting the error "ERROR TypeError: Cannot read property 'mobile_number' of undefined" and I need help in resolving this problem. <form (ngSubmit)="processForm()"> & ...

TypeScript raises an issue with a Vue component property that has been defined using vue-property-decorator

I have a Vue component with a property defined using a decorator: import { Component, Vue } from "vue-property-decorator" @Component({ props: { myId: String, }, }) class TestProp extends Vue { myFuncti ...

Issue Arising from Printing a Custom Instruction in a Schema Generated Document

When dynamically adding a directive, the directive is correctly generated in the output schema. However, it seems to be missing when applied to specific fields. Here is how the directive was created: const limitDirective = new graphql.GraphQLDirective({ na ...

Using prevState in setState is not allowed by TypeScript

Currently, I am tackling the complexities of learning TypeScipt and have hit a roadblock where TS is preventing me from progressing further. To give some context, I have defined my interfaces as follows: export interface Test { id: number; date: Date; ...

Angular2 and Typescript paired with Visual Studio 2013

Currently, I am utilizing the angular2 QUICKSTART and encountering an issue where Visual Studio fails to recognize Angular2 with typescript import Modules. However, everything else seems to be functioning correctly: https://i.stack.imgur.com/0s46Y.jpg Th ...

Tips for resolving the TypeScript error related to the global object in Node.js

I am currently working on a project following the steps outlined in this guide https://vercel.com/guides/nextjs-prisma-postgres to develop a full stack application. However, I have encountered an error with TypeScript in the code snippet below: import { Pr ...

The error message "Uncaught ReferenceError: exports is not defined and require" indicates that

I am currently developing an app using angularjs and typescript, but I've encountered a persistent error that has me stumped. Below is the snippet of my code: export var NgApp = new application.Startup(); ///<reference path="../../../../../typin ...

Ways to expand the width of mat-dialog-actions component in Angular 8

Is there a way to make the cancel and save buttons in the dialog window take up the entire available space? If anyone has any suggestions on how to achieve this, please let me know! ...

The modal popup will be triggered by various button clicks, each displaying slightly different data within the popup

As a newcomer to Angular 4, I have encountered an interesting challenge. Currently, my code consists of two separate components for two different modals triggered by two different button clicks (Add User and Edit User). However, I now face the requiremen ...

Encountered a PrismaClientValidationError in NextJS 13 when making a request

I am currently working on a school project using NextJS 13 and attempting to establish a connection to a MYSQL database using Prisma with PlanetScale. However, when trying to register a user, I encounter the following error: Request error PrismaClientValid ...

How can TypeScript be used to update the values and text of an HTML element?

Is it possible to update specific attributes of an html element using typescript? Below is the code snippet: HTML:- <a ref="#" id="userProfileName" style="padding-top: 0px; padding-bottom: 0px; padding-right: 10px; padding-left ...

Error in TypeScript - Anticipated 1-2 arguments, received either none or multiple. Code Issue TS2556

While working in JavaScript, I had no issues with this code snippet. However, when I attempted to implement it in a TypeScript Project, an error surfaced. The problem seems to revolve around the fetch(...args) function call. const fetcher = (...args) =&g ...

Guide to accessing and modifying attributes of Ionic components in TypeScript file

I am curious about how to manipulate the properties or attributes of an Ionic component from a TypeScript file. For example, if I have an input component on my HTML page: <ion-item> <ion-input type="text" [(ngModel)]="testText"></ion ...

Using discord.js to conveniently set up a guild along with channels that are equipped with custom

When Discord devs introduced this feature, I can't seem to wrap my head around how they intended Discord.GuildManager#create to function. How could they possibly have expected it to work with Discord.GuildCreateOptions#channels[0], for instance, { ...

What could be causing the table to display empty when we are passing data to the usetable function?

Visit Codesandbox to view Table While the header appears correctly, I noticed something strange. When I console log the data props, it shows all the necessary data. However, when I try to console.log row, there doesn't seem to be any single object re ...

Error encountered when attempting to utilize Path Aliases in Angular 11.tsconfig

Currently, I am working on a project using Angular 11 and aiming to utilize short imports like import {smthg} from '@common' instead of import {smthg} from '../../../common' However, I keep encountering errors in IDEA: TS2307: Cannot f ...

I am encountering a problem with my Material UI react-swipeable-views while using TypeScript

It seems that there is a mismatch in the version of some components. import * as React from "react"; import { useTheme } from "@mui/material/styles"; import Box from "@mui/material/Box"; import MobileStepper from "@mui/ma ...

Expressjs - Error: Headers already sent to the client and cannot be set

After testing various solutions from others, I am still unable to resolve this error. My objective is to iterate through each item in the array sourced below: novel.ts export let indexList = (req: Request, res: Response) => { novel.getAllDocuments ...

Executing functions in Vue TypeScript during initialization, creation, or mounting stages

Just a few hours ago, I kicked off my Vue TypeScript project. I've successfully configured eslint and tslint rules to format the code as desired, which has left me quite pleased. Now, I'm curious about how to utilize the created/mounted lifecycl ...