alteration of a function through TypeScript

export const wrapCountable = (func: Function): Function => {
    let result: Function & { __times?: number } = () => {
        //result.__times = result.__times || 0
        result.__times++
        let value = null
        try {
            value = func()
        } catch (e) {
            throw e
        }
        return value
    }
    result.__times = 0
    return result
}

This function is designed to encapsulate another function provided as an argument.

An issue arises when the strictNullChecks mode is enabled, causing errors in the IDE.

https://i.sstatic.net/LenOg.jpg

The current workaround involves adding this line of code:

result.__times = result.__times || 0

However, I am seeking a more elegant solution. What would be the correct approach?

Answer №1

The compiler may not recognize that result.__times will be defined before the arrow function in result is executed. If you prefer to avoid altering the output JavaScript, consider using the non-null assertion operator ! to assert to the compiler that you know better and that result.__times will indeed be defined:

export const wrapCountable = (func: Function): Function => {
    let result: Function & { __times?: number } = () => {
        result.__times!++ // Note the ! here
        let value = null
        try {
            value = func()
        } catch (e) {
            throw e
        }
        return value
    }
    result.__times = 0
    return result
}

This approach will suppress the error, although it is not entirely type-safe. You could remove the line result.__times = 0 and still suppress the error. Type assertions such as ! allow for potential deception of the compiler. Still, in this situation, an informed decision to use an assertion might be appropriate.

That said, a more concise version of your function could look like this:

const wrapCountable = <T>(func: () => T) => {
    const result = Object.assign(() => {
        result.__times++;
        return func();
    }, { __times: 0 });
    return result;
}

const eighteen = wrapCountable(() => 18);
// const eighteen: (() => number) & {__times: number}
console.log(eighteen()); // 18
console.log(eighteen()); // 18
console.log(eighteen.__times); // 2

This version utilizes a generic T to preserve the return value's type, employs Object.assign() to prevent __times from being undefined, and eliminates the unnecessary try/catch block which seems redundant (as re-throwing the same exception is a no-op, correct?).

Hopefully, this explanation proves helpful. Best of luck!

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

Show blank value if there are no search results, along with an additional menu option

I am currently working on a Typeahead feature with a customized menu using the renderMenu method. In this setup, I have added 2 custom menu items at the bottom - one divider and a button. An issue arises when there are no search results. If I do not inclu ...

Tips for limiting users to inputting only alphanumeric characters and excluding special characters in an input field using Angular 8

How can I prevent users from inputting special characters in an input field and only allow alphanumeric values? The code that I have implemented so far does not seem to be working as intended. When a user enters a special character, it still shows up in th ...

To validate any object, ensure that it contains a specific key before retrieving the corresponding value in typescript

When looking at a random object, my goal is to verify that it follows a certain structure. obj = {WHERE:{antherObject},OPTIONS{anotherObject}} Once I confirm the object has the key using hasProperty(key), how can I retrieve the value of the key? I thoug ...

Using Partial function input in TypeScript

I am in need of a function that can accept partial input. The function includes a variable called style, which should only have values of outline or fill, like so: export type TrafficSignalStyle = 'outline' | 'fill' let style: TrafficSi ...

Storing data from a collection of interface objects in a string array

Take a look at the following code snippet: import React, {FC} from 'react'; import {useFetchErrors} from "../Api/Api"; import {useLocation} from "react-router-dom"; interface ExecutionTableProps { project_id: number } const ...

Having difficulty locating the correct TypeScript interface for executing GraphQL queries in a React application using Apollo Client

In this React component code snippet, a table is returned with each row containing data fetched from a backend API using GraphQL. While the data is successfully fetched, there seems to be an issue in defining the correct interface for handling the data ret ...

The function 'appendChild' is not recognized on the type 'unknown'.ts(2339)

I'm encountering an issue while trying to integrate the Utterances component into my articles. Upon attempting to build the site, I receive the following error message: "Property 'appendChild' does not exist on type 'unknown' ...

Oops! We encountered an error - the object type '[object Object]' is not supported by NgFor. Remember, NgFor only works with Iterables like Arrays. This issue may be related to nested JSON data

I am attempting to bind the data from a nested Json file provided below. Unfortunately, I am encountering an error that states: "Cannot find a differ supporting object '[object Object]' of type 'object'. ngFor only supports binding to I ...

What are the benefits of precompiling my Typescript project for production instead of just running it directly with ts-node?

Many people recommend precompiling production builds. However, the reasoning behind this advice is not clear to me. What potential issues may arise from running a project in production using node --loader ts-node/esm src/server.ts ? ...

Combining the output of two Observables through the CombineLatest method to generate a

I possess two separate collections of information: Data Model: taxControlReference [ { "providerId": "HE", "taxTables": { "STAT": [ 1 ] } }, ...

Assignment of type 'Angular Promise<void>' is not compatible

In the process of developing a website with Angular4 and retrieving data from Contentful CMS API, I am encountering an issue with assigning proper types to the returned data despite seeing the correct types in the console. The example mock data is as foll ...

What sets apart a JSON Key that is enclosed in double quotes "" from one that has no quotes?

Below is my TypeScript object: { first_name:"test", last_name: "test", birthdate:"2018-01-08T16:00:00.000Z", contactNumber: "12312312312", email:"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e19 ...

Global Declaration of Third-Party Modules for Seamless Use without Imports in Webpack5 with TypeScript

Within my React project utilizing Webpack, I have opted to declare certain modules as global entities to eliminate the need for importing them every time they are needed. In my Webpack configuration file: plugins: [ new webpack.ProvidePlugin({ ...

Creating a node module using TypeScript module is a straightforward process

Steps to Convert TypeScript Module to JavaScript Module Here is my tsconfigFile configuration: { "compilerOptions": { "target": "ES5", "module": "CommonJS", "declaration": true, ...

Utilizing React Native Camera Kit allows for the seamless and continuous scanning of QR codes, offering multiple callbacks when a code is

Attempting to integrate a QR code scanner into my project using react native. Utilizing the plugin react-native-camera-kit, which supports both QR and Bar code scanning. However, I am facing an issue where the scanner continuously scans the code and trig ...

how to enhance Request type in Express by adding a custom attribute

In my quest to create a custom middleware function in Node.js using TypeScript, I am facing an issue where I am trying to save a decoded JSON web token into a custom request property called 'user' like so: function auth(req: Request, res: Respo ...

How can I design a Typescript interface that accommodates both strings and other data types?

I am working on designing an interface that allows for an array of objects and strings to be stored. For instance: const array = [ '', {id: '', labels: ['']} ] I attempted to achieve this using the following code: export ...

Using checkboxes for filtering in a React application

Here are the data sets I am working with: const dataSet = [ { id: 1, title: 'object1', published: true, }, { id: 2, title: 'object2', published: true, }, { id: 3, title: 'object3', ...

The rendering process in ag-grid is resulting in the service component initialized from an event to become null

Currently, I am utilizing ag-grid and need help understanding a specific issue. In my method for preparing GridOptions, I have set up an onCellValueChanged event that triggers a service component to access the database and populate the data. However, when ...

Redis throwing an error - when handling an event

import * as redis from 'redis' import configuration from '../../configuration/settings' const customer = redis.createCustomer(configuration.redis.port, endpoint, configuration.redis.options); customer.on('active', () => { ...