Typescript: The function parameter in a class method is more specific than in the superclass

I am facing an issue with two TypeScript classes where one extends the other:

type NamedObject = {
    name: string;
}

class AnyObjectManager {
    objectList = [];
    getAnyObject = (matches: (o: object) => boolean) => {
        for (const o of this.objectList) {
            if (matches(o)) {
                return o;
            }
        }
        return null;
    }
}

class NamedObjectManager extends AnyObjectManager {
    getObjectNamedTim = () => {
        return this.getAnyObject(this.objectIsNamedTim)
    }
    objectIsNamedTim = (namedObject: NamedObject) => {
        return namedObject.name === 'Tim';
    }
}

An error is being displayed by TypeScript in the method NamedObjectManager.getObjectNamedTim:

TS2345: Argument of type '(namedObject: NamedObject) => boolean' is not assignable to parameter of type '(o: object) => boolean'.   
Types of parameters 'namedObject' and 'o' are incompatible.     
Property 'name' is missing in type '{}' but required in type 'NamedObject'.

I want to ensure that all objects managed by NamedObjectManager will be NamedObjects, as functions like addObject guarantee this. How can I communicate to TypeScript that we can safely assume this in methods inherited from the parent class?

Answer №1

If you want to manage objects in a "type safe" way, consider using generics:

class AnyObjectManager<T> {
    objectList: T[] = [];
    getAnyObject = (matches: (o: T) => boolean) => {
        for (const o of this.objectList) {
            if (matches(o)) {
                return o;
            }
        }
        return null;
    }
}

class NamedObjectManager extends AnyObjectManager<NamedObject> {
    getObjectNamedTim = () => {
        return this.getAnyObject(this.objectIsNamedTim)
    }
    objectIsNamedTim = (namedObject: NamedObject) => {
        return namedObject.name === 'Tim';
    }
}

Check out the Playground to see it in action.


In addition, you can simplify getAnyObject as follows:

getAnyObject = (matches: (o: T) => boolean) => this.objectList.find(matches) || null;

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

Redeclaring block-scoped variable 'reducer' is not allowed in TypeScript

I encountered an error message Cannot redeclare block-scoped variable 'reducer' when running sample code from a book using tsc. I'm unsure of the reason behind this issue. tsc -v // Version 2.1.0-dev.20160726 Next, I executed ts-node in t ...

Check to see if the upcoming birthday falls within the next week

I'm trying to decide whether or not to display a tag for an upcoming birthday using this boolean logic, but I'm a bit confused. const birthDayDate = new Date('1997-09-20'); const now = new Date(); const today = new Date(now.getFullYear( ...

Is the return type determined by the parameter type?

I need to create an interface that can handle different types of parameters from a third-party library, which will determine the return type. The return types could also be complex types or basic types like void or null. Here is a simple example demonstra ...

Partial specialization of member functions in C++ templates

I am experimenting with specializing geometric functions based on whether they are 2D or 3D, represented by a template parameter. Below is a snippet of some (very flawed) code for a simplistic version of the issue: template <typename T, int d> class ...

error message when trying to use member function in class that is not a class type

I am trying to create a simple class called Box, which represents a box and has a vector data member to store its dimensions. I want to be able to pass the dimensions as an argument when creating an instance of the class. There is also a member function ...

Converting TypeScript into JavaScript files within an ASP.NET SPA application

As I work on my current project using ASP.NET spa and Vue.js, I have been serving the dist folder from the Vue.js client app statically. This dist folder contains the compiled result of the client app's /src directory, where all .Vue and .ts files are ...

Encountering a tsx-loader issue when integrating tsx with vuejs

I've been attempting to integrate TSX with Vuejs based on several blog posts, but I'm consistently encountering the error displayed below. I cloned a starter kit from GitHub and it worked fine, leading me to believe that there may be an issue wit ...

The ngOnChanges lifecycle hook does not trigger when the same value is updated repeatedly

Within my appComponent.ts file, I have a property called: this._userMessage Afterwards, I pass it to the childComponent like so: <child-component [p_sUserMessage]='_userMessage'></child-component> In the childComponent.ts file: @ ...

Determine the generic parameter of the output type by analyzing the resolved value of a data type within the function

I am looking to automatically determine the generic parameter of the return type by utilizing the resolved value of a type within the function. Consider the following: export type Context = any; export type Handler<T> = (ctx: Context) => Promise& ...

Ensure the safety of TypeScript class decorators by specifying the constructor function type

Consider the following decorator: export function MyDecorator(constructor: new(someService: SomeService, ...args) => ISomeInterface) { when incorporating it within an Angular component, I require the compiler to verify that the service injection is not ...

Passing a type as an argument in Typescript

How can I pass a type as a parameter in Typescript? type myType = {} const passingType = (t: Type) => { const x : t = {} } passingType(myType); I keep receiving TypeScript errors. 't' is referencing a value, but it is being used as a t ...

Strategies for handling asynchronous requests and effectively presenting the retrieved data

On my HTML page, I have a badge component that shows the number of unread messages. Here is the HTML code: <button class="font" mat-menu-item routerLink="/message"> <mat-icon>notifications</mat-icon> <span [matBadgeHidden]="newM ...

What is the correct method for retrieving MySQL results in a Node.js function callback?

Seeking guidance on the proper method to extract the outcome of this MySQL Query from GetAllFarms and store it in variables named err and farms. Transitioning from a different programming language, so assistance is needed. var err, farms = GetAllFarms() ...

Adding an external component to an Angular 2 project

I've been facing challenges while trying to import an external component from a URL into a new Angular2 application. The issue I keep encountering is with the typescript failing to compile and run the application smoothly. Here is the specific import ...

Error: Unhandled promise rejection - The function get is not part of this.categoryMap

I am facing an issue with calling functions of the Map (get, set, keys, etc) within my function. The map I am working with is returned from a firebase query. Here's a snippet of my code: categoryMap = new Map<Number, String>(); //called onInit ...

Why is the type considered a union when comparing any to void?

I was curious to see what would happen when a type was checked if it was void, and I found the result interesting. It seems that when the input is any, a union is returned. Can someone shed some light on why this occurs? type test<T> = T extends void ...

The element 'stripe-pricing-table' is not a recognized property of the 'JSX.IntrinsicElements' type

I am currently trying to incorporate a pricing table using information from the Stripe documentation found at this link. However, during the process, I encountered an issue stating: "Property 'stripe-pricing-table' does not exist on type &ap ...

Working with an arbitrary number of arguments in TypeScript

Looking for a way to pass an arbitrary number of arguments with different types into a function and utilize those types, similar to the following: function f<A>(a: A): A; function f<A, B>(a: A, b: B): A & B; function f<A, B, C>(a: A, ...

getting TypeScript configured with webpack

I am currently using Typescript to develop a back-end API utilizing graphql and express. To manage the project development and building process, I have implemented webpack. As part of my setup, I am employing raw-loader in order to load graphql schemas an ...

An issue occurred while creating a generic MessageBus in Typescript with rxjs due to a typing mismatch

I'm currently working on developing a versatile MessageBus in Typescript. My goal is to create message classes that inherit from a main MessageBusMessage class, allowing for subscription to messages of a specific class type with strong generic typing ...