Leverage TypeScript's ability to automatically deduce function parameters from the specified function return type

Is it feasible to deduce the type of a function parameter from the declared return type of the function?


type MyFunc = any // <--- How can this be done?

const myFunc: MyFunc = (param): { foo: boolean } => {
  return { foo: true }             // ^ This should determine the type of param
            // ^ No additional properties permitted here!
}

UPDATE: I intend to define the MyFunc type in a way that when hovering over the param argument, it displays boolean as the type, simply because the declared function type is boolean.

Is this achievable?

Check out this live demo.

ANOTHER UPDATE: I modified the return type from boolean to { foo: boolean }. I want the return type to disallow extra properties.

Answer №1

It doesn't seem possible to achieve your desired outcome in the exact way you want. This would necessitate the use of a generic, leading to the common error message: "Type '{foo: boolean}' is not assignable to type 'T'...'T' could be instantiated with an arbitrary type which could be unrelated to '{foo: boolean}'." You can see an example of this error here.

However, if you transfer your {foo: boolean} from the function return to the constant's type annotation, you can avoid encountering that problem:

type MyFunc<T> = (param: T) => T;

const myFunc: MyFunc<{foo: boolean}> =    (param) => {
// Move here −−−−−−−^^^^^^^^^^^^^^^^− instead of ^
    return {foo: true};
};

Playground link


In a subsequent edit after this answer was published, you mentioned wanting to avoid extra properties on the returned object (originally it was not even an object). This raises a completely different question and should be addressed separately (if it hasn't already been). Note that excess property checks are applied very selectively in TypeScript. I don't have precise details, but the types must be closely defined for excess property checks to take place.

To illustrate how limited their application is, they apply in this scenario (link):

const example = (): {foo: boolean } => {
    return {foo: true, bar: false};
    //                 ^− Type '{ foo: true; bar: boolean; }' is not assignable to type '{ foo: boolean; }'.
    //                      Object literal may only specify known properties, and 'bar' does not exist in type '{ foo: boolean; }'.
};

...but not in this case (link):

type ExampleFunction = () => {foo: boolean };
const example: ExampleFunction = () => {
    return {foo: true, bar: false};
    // No error here −−^
};

It's unlikely that these checks will be applicable to your specific situation, prompting the need for a separate inquiry from the original one that was asked and answered.

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

What prevents using super() to set values on an immutable record?

I'm in the process of setting up a brand new Redux store state, starting from scratch. Instead of reinventing the wheel, I decided to replicate an existing Redux store structure that I had previously created and simplified. Initially, I attempted to ...

Utilizing a variable to pass props to a component (instead of a static component) within React Router 5

In react-router 5, you can pass props to a child component in this way: <Route path="/" exact render={ props => <MyPage title={myTitle} dataPath={myDataPath} {...props} />} /> However, I am using a route model in my ...

Is it possible to assign a string literal type as a key in TypeScript mappings?

Is it possible to map a string literal type as a key in a new type? I attempted this, but it did not work as expected. const obj = { type: "key", actions: { a() {}, b() {}, }, } as const; /* Map to { key: { a() {}, b() {}, } */ t ...

What advantages does utilizing Jasmine Spy Object provide in Angular Unit Testing?

I have a question regarding unit testing in Angular using Jasmin/Karma. Currently, I am working with three services: EmployeeService, SalaryService, and TaxationService. The EmployeeService depends on the SalaryService, which is injected into its constru ...

What is the best way to set types using UseState and Firebase snapshot when needing to utilize the .map function on the data?

Snippet of Code: const [posts, setPosts] = useState([]); useEffect( () => onSnapshot( query(collection(db, "posts"), orderBy("timestamp", "desc")), (snapshot) => { setPosts(snapshot. ...

Angular2/TypeScript Coding Guidelines

I am curious about the common practices and consensus among the Angular2 community when it comes to writing reusable code in TypeScript. I have gathered some information and questions related to Angular2 that I would like to discuss. Organizing Module/A ...

Interfaces in Typescript fail to enforce explicit type checking on function arguments

Upon compiling the code below, I anticipated encountering TWO errors. However, to my surprise, Typescript compiled it flawlessly without any errors. interface IFoo{ Bar(callback: (arg:string) => void):void; } class Foo implements IFoo { public ...

Select and activate a single input from multiple options in Angular

I have multiple input fields with corresponding buttons that enable the input when clicked. I would like the behavior of the buttons to work in such a way that when one button is clicked, only that specific input field is enabled while the others are disab ...

Utilizing defaultProps with forwardRef in TypeScript

I am facing an issue with using defaultProps in forwardRef. Everything works fine when I use MessageBox without forwardRef and defaultProps. But, once I implement forwardRef along with defaultProps, an error is triggered. Any suggestions on how to resolve ...

UI not reflecting updated form validation after changes made

Currently, I have a situation where I am passing a form from the Parent component to the Child component. All the validations are being handled in the Parent component and the Child component is simply rendering it. However, there is a specific field calle ...

What is the outcome when the return type is a string or a function that takes validation arguments and returns a string?

This excerpt is extracted from line 107 over here. From my understanding, it indicates: The function either returns a string directly or a function that accepts ValidationArguments as input and then produces a string output. Given that this is new to m ...

Tips for utilizing $rootScope define within one angular service in another service with typescript

Within a service class, I have initialized a $rootScope in the constructor and assigned a property to it using this.$rootScope. However, when attempting to access this property in another service within the same class, a new $rootScope is created and the p ...

The SupabaseAuthClient type does not have a property named 'session' available

Here is the complete code snippet for page.tsx: "use client"; import React, { useState, useEffect } from "react"; import axios from "axios"; import { Session } from "@supabase/supabase-js"; import { Auth } from " ...

What are the necessary peer dependencies for Angular-compatible projects?

In the process of integrating RxJS as a peer dependency for my Angular 6 project, I encountered an interesting declaration method. Take, for instance, angular/flex-layout, which declares its RxJS dependency in this manner: "requiredAngularVersion": ">= ...

What is the best way to assign the value of an HTTP GET request to a subarray in Angular 8

Attempting to store data in a sub-array (nested array) but despite receiving good response data, the values are not being pushed into the subarray. Instead, an empty array is returned. for (var j=0;j<this.imagesdataarray.length;j++){ this.http.g ...

Apologies, the module "@org-name/package-name" could not be located

I've hit a roadblock for the past few days. My goal is to create a new npm package that wraps an API I've been developing. When bundling the package, everything seems to be fine in the /dist folder. However, when attempting to test it in a front ...

Integrating d3.js into an Angular 2 project

Trying to incorporate the d3.js library into a MEAN application using angular2. Here are the steps I've taken: npm install d3 tsd install d3 In mypage.ts file (where I intend to show the d3.js graph) // <reference path="../../../typings/d3/d3.d ...

Can a TypeScript interface be exported as the result of a function?

Looking for a way to convert JSON schema to a Typescript interface in a more efficient manner. Here is an example of what the current method looks like: //Input var scriptSchema = { type: 'object', properties: { src: { type: &apo ...

Is it possible to include the selected option name in an ngModelChange method in Angular?

Is it possible to pass the name for the select option into industryChange() instead of the value ($event)? I tried passing industry.name in my example below, but it didn't work! Check out my select list: <div class="form-group col-md-4"> & ...

Blazing Paths with an Isomorphic Application Using Inferno and TypeScript

I am currently working on building an isomorphic application using Express and Inferno. Strangely, I have not come across any similar projects online. In my attempt to create one myself by following a guide on Razzle, specifically related to Inferno, I enc ...