Can certain methods be designated to always return a specific type of value?

Can TypeScript define an interface that will only be applied to methods starting with a specific word and enforce them to have a certain return type? I had the idea of:

interface IPattern {
   [k: 'handle' + string]?: () => SomeClass
}

This would mean that a class implementing IPattern would need to have methods starting with 'handle' returning a SomeClass object, while other methods would not, for example:

class ForcedClass implements IPattern{
   foo(): number; // ok
   handleFoo(): SomeClass; // ok
   handleBar(): number; // error
}

Although I could use an abstract class containing all the required methods, it would be tedious to create one for each implementation given that the handle + something combination is used in multiple scenarios;

Answer №1

If you want to achieve something similar, you can utilize an index signature along with template literal types:

interface IPattern {
   [k: `handle${string}`]: () => SomeClass
}
class CustomClass implements IPattern{
   [k: `handle${string}`]: () => SomeClass
   foo(): number { return 0 } // Valid
   handleFoo(): SomeClass { return "0 "} ; // Valid
   handleBar(): number{ return 0 }  // Error
}

new CustomClass()['handleBaz'](); // This is allowed due to the index signature
new CustomClass().handleBaz(); // This is also allowed due to the index signature

Playground Link

An issue with using the index approach is that while it validates the class members, it allows indexing with any value that fits the handle${string} template literal type, even if the member isn't part of the class.

Alternatively, you can use a type to validate actual keys of the class without needing the index signature:

type IPattern<T> = Record<Extract<keyof T, `handle${string}`>, () => SomeClass>;

class CustomClass implements IPattern<CustomClass> {
   foo(): number { return 0 } // Valid
   handleFoo(): SomeClass { return "0 "} ; // Valid
   handleBar(): number{ return 0 }  // Error
}

new CustomClass().handleBaz(); // Results in error
new CustomClass().handleFoo(); // Allowed

Playground Link

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

Customize the format of data labels in horizontal bar charts in NGX Charts

I am currently using ngx-charts, specifically the bar-horizontal module. My goal is to format the data labels and add a percentage symbol at the end. I attempted to use the [xAxisTickFormatting] property, but it seems that my values are located within the ...

Facing a problem with querying interfaces and types in TypeScript

My goal is to pass a variable to an RTK Query API service that uses a typescript interface: const device_id: unique symbol = Symbol(props.id); const { data: device, isFetching, isLoading, } = useGetAssetsByIdQuery(device_id, { pollingInterv ...

RxJS - Only emit if another source does not emit within a specified time frame

Imagine having two observables. Whenever the first one emits, there should be a 2-second pause to check if the other observable emits something within that timeframe. If it does, then no emission should occur. However, if it doesn't emit anything, the ...

What is the method for retrieving array values from an attribute?

I am currently developing an Angular 6 application and I need to pass and retrieve array values dynamically through attributes. Here is the code snippet I have used for this purpose: HTML: <ul class="list-unstyled" id="list" [attr.parent_id]="123"> ...

Is it possible to distribute the outcome of a function call into properties in JSX?

I'm struggling to figure out how to achieve this, but here is what I'm aiming for: <ColumnDef key="label" ...createCommonColumnProps.call(this, {somestuff}) /> <ColumnDef key="count" ...createCommonColumnProps.call(this, {someOtherStuff ...

Selecting the Appropriate Table Columns to Display

I currently have a table that includes columns for first name, last name, place of birth, date of birth, and three additional fields. Positioned above the table is a button that triggers a modal window containing checkboxes representing each column. Below ...

Typescript typings for child model/collection structures

I have encountered an issue while trying to implement a Model/Collection pattern with various typings. Both the Model and Collection classes have a method called serialize(). When this method is called on the Collection, it serializes all the Model(s) with ...

Using Typescript to pass a property as one of the keys in an object's list of values

In my React Native project, I need to pass a string value from one component to another. The different options for the value can be found in the ScannerAction object: export const ScannerAction = { move: 'move', inventory: 'inventory&apo ...

Oops! Slim-loading-bar encountered an error because it was unable to locate the module '@angular/core'

I am currently learning Angular and attempting to integrate the ng2-slim-loading-bar. However, I encountered the following error - ERROR in ../node_modules/ng2-slim-loading-bar/index.d.ts(1,37): error TS2307: Cannot find module '@angular/core'. ...

I'm looking to filter this array based on the value of a subarray that the user will specify the key and value for. How can I accomplish

Given the input var key="value_0" and var input="hello", I need to filter the array in TypeScript based on these values. The filtering criteria involve checking if the array elements contain a subarray with key="value_0" and if the value of this key includ ...

Employing square bracket notation based on the input data

I'm currently in the process of enhancing some code within my library, but I've encountered a perplexing issue with bracket notation not functioning as expected when attempting to call an imported class. The parameter type expects a camelCased s ...

Performing actions simultaneously with Angular 2 directives

My custom directive is designed to prevent a double click on the submit button: import { Directive, Component, OnInit, AfterViewInit, OnChanges, SimpleChanges, HostListener, ElementRef, Input, HostBinding } from '@angular/core'; @Directive({ ...

Incorporating the non-typescript npm package "pondjs" into Meteor applications using typescript files

Implementing the Pondjs library into my project seemed straightforward at first: meteor npm install --save pondjs However, I'm encountering difficulties when trying to integrate it with my Typescript files. The documentation suggests: In order ...

Can a TypeScript function be structured to return never (or throw) if a generic type extends a subtype without requiring casting?

(This code snippet is purely for demonstration purposes, as no real use-case exists here) I am attempting to create a function that throws an error if the input string is equal to "fish". I have achieved this using the as keyword, but I am curious if ther ...

Error in Typescript: Unable to assign type 'string' to the specified custom type

I am encountering an issue with a type definition like this: interface StyleProps { display?: 'hide' | 'active' } This type is then utilized by the component below: <Section display={`${this.state.section !== 'chatbot' ...

You cannot assign type void to type any

I'm currently working on a component that involves some code: export class AddNewCardComponent { public concept = []; constructor( private _router: Router, private _empDiscService: empDiscService) { } ngOnIni ...

Tips for structuring TypeScript with MobX in a ReactJS project

I created a MobX store as shown below. I defined the types of actions in store.js import { action, observable } from 'mobx'; export class SignStore { @observable UserInformation: { email: ''; password: ''; ...

Tips for configuring Visual Studio Code to utilize path mappings for handling automatic imports

In order to streamline my project and avoid messy paths, I am implementing absolute paths that will allow for consistent imports regardless of the file's location in the project tree. For this purpose, I made adjustments to the tsconfig.json: "paths ...

Troubleshooting an Issue in VBA Excel with Utilizing a Collection of Custom Objects within a Custom Object

Feeling frustrated here. I seem to be missing something obvious, but just can't figure it out. Any assistance would be greatly appreciated. As a beginner, I'm sure I must be making a basic mistake somewhere. The issue at hand is as follows: I h ...

A utility type in Typescript for managing default database schema values

I am currently exploring a method for incorporating default and virtual values in a database schema. The concept involves using a utility type to automatically convert a schema for insertion (props with defaults or generated by virtuals aren't necessa ...