Declaration of function with extra attributes

Is there a way to define a type for a function that includes additional properties like this?

foo({ name: 'john' })
foo.type

I tried the following solution, but TypeScript seems to think that foo only returns the function and cannot be called with the payload argument.

type FunctionWithType = {
  (): (payload: { name: string}) => ({ type: string; payload: { name: string }});
  type: string
}

You can view the playground with the example above and my attempt at a solution here (edited)

Answer №1

For more insights, please refer to a related question.

Take a look at this example:

type FuncWithType = {
    (): (payload: { name: string }) => ({ type: string; payload: { name: string } });
    type: string
}

const foo: FuncWithType = () => {
    return (payload) => ({
        type: 'foo',
        payload
    })
}

foo.type='hello'

Use the Playground here

Remember, the way you define FuncWithType requires a function that returns another function. The syntax

(): (payload: { name: string }) => ({ type: string; payload: { name: string } }); 
signifies a function with no arguments () that returns a function taking payload.

If you need to declare a non-curried function type, you can use this format:

type FuncWithType =
    & ((payload: { name: string }) => ({ type: string; payload: { name: string } }))
    & {
        type: string
    }

const foo: FuncWithType = (payload) => ({
    type: 'foo',
    payload
})

foo.type = 'hello'

Answer №2

Generics can be utilized for this purpose:

TS Playground link

type FuncWithExtraProps<T> = T & {
  <P>(payload: P): T & { payload: P };
}

declare const foo: FuncWithExtraProps<{ type: string }>;
foo.type
const result = foo({ name: 'john' });

You are also able to impose restrictions on the parameter type(s):

TS Playground link

type Fn<
  Params extends unknown[] = any[],
  Result = any,
> = (...params: Params) => Result;

type FuncWithExtraProps<ExtraProps, Payload> = (
  Fn<
    [payload: Payload],
    ExtraProps & { payload: Payload }
  >
  & ExtraProps
);

declare const foo: FuncWithExtraProps<{ type: string }, { name: string }>;
foo.type
const result = foo({ name: 'john' });

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

Create an asynchronous method within an object-oriented programming (OOP) class

Presenting my Activity class. export class Activity { _name: string _goIn: boolean constructor(name: string) { this._name = name; this._goIn = false; } isGoIn() { return this._goIn; } setGoIn() { // instructions to asyn ...

Unable to call an object that may be 'undefined': Utilizing a function with a return object that includes asynchronous functions as properties

I have a function exported in my adapter.ts file: import type { Adapter } from "@lib/core/adapters"; export default function MyAdapter (): Adapter { return { async createUser (user: User) { ... }, async findUserByEmail (email ...

Is there a way to transform time into a percentage with the help of the moment

I am looking to convert a specific time range into a percentage, but I'm unsure if moment.js is capable of handling this task. For example: let start = 08:00:00 // until let end = 09:00:00 In theory, this equates to 100%, however, my frontend data ...

When importing a module, the function in the ts file may not be recognized or located

While attempting to create a VSTS (Azure Devops) Extension, I encountered a perplexing issue. Within my HTML page, I have a button element with an onclick listener: <!DOCTYPE html> <head> <script type="text/javascript"> VS ...

Support different response types when making nested API calls

When working with two API calls that return different responses, one typed as TestData1Res and the other as TestData2Res, how can I handle the scenario where the response could be either type and process the property? `TestData1Res{ testData: string } Te ...

Creating specific union types for a bespoke React hook

There are 4 objects with both similar and different keys. The union of these objects is used for database operations as follows -> type Objects = Food | Diary | Plan | Recipe ; A Custom Pagination Hook function usePaginate (key: string, options: Option ...

The program encountered an unexpected symbol. It was expecting a constructor, method, accessor, or property. Additionally, there is a possibility that the object is 'undefined'

Can someone please help me figure out what's wrong with this code snippet? import cassandra from "cassandra-driver"; class Cass { static _cass : cassandra.Client; this._cass = new cassandra.Client({ contactPoints: ['localhost&ap ...

The counterpart of the RxJS setTimeout operator

Looking for a RxJS operator alternative to set/clearTimeout in these circumstances: this.mouseEnterSubscription = this.mouseEnterStream .subscribe(() => { this.timeout = setTimeout(() => { void this.playVideo(); }, 500) }); this.mo ...

Troubleshooting Issue with Filtering Nested Object Array Based on Property

At the core of my data structure lies an array of orders, each containing an array of line items. These line items, in turn, are associated with their respective categories. I am currently attempting to filter the order array based on the category ID of th ...

Having difficulty accessing certain code in TypeScript TS

Struggling with a TypeScript if else code that is causing errors when trying to access it. The specific error message being displayed is: "Cannot read properties of undefined (reading 'setNewsProvider')" Code Snippet if (this.newsShow != ...

Prevent Typescript from flagging unnecessary warnings about unassigned values that will never be assigned

One of my functions serves as a shortcut for selecting values from synchronous observable streams. The function in its entirety looks like this: export function select<T>(inStream: Observable<T>): T { let value: T; race( inStream, ...

TypeScript/Javascript - Error: The specified function is not callable

After recently delving into TypeScript, I found myself encountering an error in my code for a wheel mini-game on my app. The specific error being displayed in the console is: this.easeOut is not a function The relevant portion of the code causing the iss ...

Iterating over a JSON array using *ngFor

Here is the JSON structure that I have: { "first_name": "Peter", "surname": "Parker", "adresses": { "adress": [{ "info1": "intern", "info2": "bla1" }, { "info1": "extern", "info2": "bla2" }, { "info1": " ...

Proper method of managing undeclared declaration files (index.d.ts)

I encountered the following error message: error TS7016: Could not find a declaration file for module 'react-native-camera'. '/Users/ilja/Documents/Repositories/blok/node_modules/react-native-camera/index.js' implicitly has an 'an ...

Retrieving a nested type based on a particular condition while keeping track of its location

Given an object structure like the one below: type IObject = { id: string, path: string, children?: IObject[] } const tree = [ { id: 'obj1' as const, path: 'path1' as const, children: [ { id: &ap ...

Using TypeScript to consolidate numerous interfaces into a single interface

I am seeking to streamline multiple interfaces into one cohesive interface called Member: interface Person { name?: { firstName?: string; lastName?: string; }; age: number; birthdate?: Date; } interface User { username: string; emai ...

What is the process for assigning a predefined type that has already been declared in the @types/node package?

Is there a way to replace the any type with NetworkInterfaceInfo[] type in this code snippet? Unfortunately, I am unable to import @types/node because of an issue mentioned here: How to fix "@types/node/index.d.ts is not a module"? Here is the o ...

The TypeScript error TS2307 occurs when my module cannot be located in the index.d.ts file

I'm encountering an issue that is giving me trouble. I need to share some interfaces and types across my class files. The structure of my repository looks like this: test -> dist/ -> src/ -> index.ts -> .babelrc -> .eslintr ...

A new issue arises after merging in Google Datastore, as an unexpected property is

Currently, I am working on developing an API in Typescript to interact with a Google Cloud Datastore instance for storing and retrieving entities. So far, I have successfully implemented the GET, POST, and DELETE methods. However, I encountered an issue w ...

What steps do I need to take to develop a personalized validation directive (an attribute used for validation) in Angular 2.0?

I have embarked on a small project involving Angular 2.0 and TypeScript. From what I understand, Angular 2.0 does not come equipped with built-in validators for the "min" and "max" attributes. I am aware of the process to create a custom validator and asso ...