Determine the type of the final function within a variable number of nested closures

Imagine you have a function like this:

const f = a => b => ... x => { return somevalue }

Is there a way to determine the type of just the final function

typeof x => { return somevalue }
even if we don't know how many closures come before it?

One idea is to create a type that uses recursion and conditional type checking to navigate through the closures until reaching the end. However, it's unclear if TypeScript supports recursive types for solving this specific issue.

Answer №1

Recursive conditional types are set to debut in TypeScript 4.1. In the meantime, you can access this feature by using typescript@next. Once available, you'll be able to define something like:

type LastFunc<T extends (...args: any) => any> =
    T extends (...args: any) => infer R ? 
    R extends (...args: any) => any ? LastFunc<R> : T : never;

You can apply it to your function f as follows:

declare const somevalue: SomeValue;
const f = (a: any) => (b: any) => (c: any) => (d: any) => (x: any) => { return somevalue }
type LastFuncF = LastFunc<typeof f>; // type LastFuncF = (x: any) => SomeValue

Playground link to code


In the interim, there are two ways to achieve similar results. The first is a workaround that may not be officially supported but gets the job done:

type LastFunc<T extends (...args: any) => any> =
    T extends (...args: any) => infer R ? {
        0: LastFunc<Extract<R, (...args: any) => any>>, 1: T
    }[R extends (...args: any) => any ? 0 : 1] : never

The second method involves manually unrolling the loop to a fixed depth which can be tedious and repetitive:

type LastFunc<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R extends (...args: any) => any ? LF0<R> : T : never;
// Additional LFX definitions...

Playground link to code


If I were in your shoes, I'd recommend waiting for TypeScript 4.1's release. Best of luck with your coding endeavors!

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

Using TypeScript to extract types from properties with specific types

My current challenge involves working with a filter object derived from an OpenAPI spec. The structure of this object is illustrated below: export interface Filters { field1: string[] field2: string[] field3: boolean field4: number } My goal is to ...

Inadequate data being sent to the server from Angular2 post request

Currently, I have a form field whose value I am passing to a service as this.form.value. However, when I log this.form.value on the console, I see Object { email: "zxzx", password: "zxzxx" }. Despite this, when I send the same data to the service and make ...

Adjust the component's input value using a different component

Let's talk about two components in this scenario - HomeComponent and UserComponent. The UserComponent is a child of the HomeComponent and has the following structure: UserComponent.html: <form [formGroup]="form"> <div style="display:block ...

Error encountered in Node.js OpenAI wrapper: BadRequestError (400) - The uploaded image must be in PNG format and cannot exceed 4 MB

Attempting to utilize the OpenAI Dall-e 2 to modify one of my images using the official Nodejs SDK. However, encountering an issue: This is the snippet of code: const image = fs.createReadStream(`./dist/lab/${interaction.user.id}.png`) const mask = fs.c ...

The StreamingTextResponse feature is malfunctioning in the live environment

When I share my code, it's an API route in Next.js. In development mode, everything works as expected. However, in production, the response appears to be static instead of dynamic. It seems like only one part of the data is being sent. I'm puzzl ...

Encountering issues when trying to build a Nestjs app with node-crc (rust cargo) in Docker

I am encountering an issue with building my Nest.js app using Docker due to a dependency called "node-crc" version "2.0.13" that fails during the docker build process. Here is my Dockerfile: FROM node:17.3.1-alpine RUN curl https://sh.rustup.rs -sSf | sh ...

Exploring the synergies between Typescript unions and primitive data types in

Given the scenario presented interface fooInterface { bar: any; } function(value: fooInterface | string) { value.bar } An issue arises with the message: Property 'bar' does not exist on type '(fooInterface | string)' I seem ...

Is it possible to remove a complete row in Angular 2 using Material Design

JSON [ { position: 1, name: 'test', value: 1.0079, symbol: 'HHH' }, { position: 2, name: 'test2', value: 4.0026, symbol: 'BBB' }, { position: 3, name: 'test3', value: 6.941, symbol: 'BB' }, ...

Tips for triggering functions when a user closes the browser or tab in Angular 9

I've exhausted all my research efforts in trying to find a solution that actually works. The problem I am facing is getting two methods from two different services to run when the browser or tab is closed. I attempted using the fetch API, which worke ...

How to Set Focus on an Input Field in an Angular 2 Modal

I'm currently working with modals in an angular project and I have a requirement to focus on a specific field within the modal. This particular field is a part of a @component: Autocomplete.html <div #autocomplete> <input #input requ ...

Is there a method to incorporate a click event for the confirm button in the ElMessageBox UI element?

When I try to remove data from the table, I need a warning message to appear in the center of the screen first. The delete function is already set up, but I'm struggling to figure out how to implement a confirm button click event with ElMessageBox. I ...

Is there a way to ensure that in React (Typescript), if a component receives one prop, it must also receive another prop?

For instance, consider a component that accepts the following props via an interface: interface InputProps { error?: boolean; errorText?: string; } const Input = ({error, errorText}: InputProps) => { etc etc } How can I ensure that when this com ...

The attribute 'attribs' is not found on the 'Element' type in cheerio

When I run my code, I encounter an error that says Property 'attribs' does not exist on type 'Element'. It's puzzling to me why this error is being thrown. After examining the type definitions of cheerio, I discovered that attribs ...

Instructions on invoking a function from another Material UI TypeScript component using React

In this scenario, we have two main components - the Drawer and the AppBar. The AppBar contains a menu button that is supposed to trigger an event opening the Drawer. However, implementing this functionality has proven challenging. I attempted to use the li ...

Exploring the money library in typescript after successfully installing it on my local machine

I've been struggling to set up a new library in my TypeScript project for the first time, and I can't seem to get it functioning properly. The library in question is money. I have downloaded it and placed it in the root of my project as instructe ...

What is the reason behind the file not found error encountered when running Deno with the command "echo hello"?

Exploring Deno's standard library, I encountered an issue with Deno.run - a function designed to create a new subprocess. Here is the example provided in the documentation: const p = Deno.run({ cmd: ["echo", "hello"], }); When I attempt to run ...

Next.js API is throwing a TypeError because req.formData is not a recognized function

Below is the code snippet for the Next.js route I am working on: import { NextRequest, NextResponse } from 'next/server'; export const config = { runtime: 'edge', }; export default async function POST(req: NextRequest): Promise< ...

The data type 'string' cannot be assigned to type 'E164Number' in the react-phone-number-input component

I'm currently utilizing a library called react-phone-number-input. Within my project, I have two important files: index.tsx and useLogicRegister.ts. While working on my code, I encountered an error stating Type 'string' is not assignable to ...

State does not contain the specified property - Navigating with React Router Hooks in TypeScript

I've been experiencing issues when using react-router-dom hooks with TypeScript. Whenever I try to access a state property, I get an error stating that it doesn't exist. For more information, you can visit: To continue development, one workaro ...

Issue encountered when importing a font in TypeScript due to an error in the link tag's crossorigin

How do I troubleshoot a TypeScript error when importing a custom font, such as a Google font? <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> Below is the specific error message: Type 'boolean' is ...