Adjust the field type to supersede the type of the generic object

I'm looking to set the type of T (a generic) equal to the type of the listener field, so that I can have auto completion for "firstParameter" whether the listener is the default value or a custom one. Is this achievable? If not, is there another solution besides setting everything to 'any'?

Currently, I am only able to have one type at a time, either dummy or upper, but not both simultaneously.

Here is the code snippet:

const upper = ({ helloWorld }: { helloWorld: string }) =>
    helloWorld.toUpperCase();

const dummy = ({ worldHello }: { worldHello: string }) => worldHello;

type objType<T extends (...args: any[]) => any = typeof upper> = {
    listener?: T;
    firstParameter: Parameters<T>[0];
};

const obj: objType = {
    listener: upper,
    firstParameter: {
        helloWorld: "hello world", // auto completion
    },
};

let arr: objType[] = [
    obj,
    { listener: dummy, firstParameter: { worldHello: "world hello" } },
]; // desired outcome

let dummyObj: objType = {
    listener: dummy,
    firstParameter: {
        // I want auto completion here without specifying the type with objType<typeof dummy>
    }
}

Playground Link

Answer №1

To achieve your desired outcome, you can create a union of possible values in the following way:

type makeObjType<fns extends (...args: any[]) => any> = fns extends fns ? {
    listener?: fns;
    firstParameter: Parameters<fns>[0];
} : never;

type objType = makeObjType<typeof upper | typeof dummy>;

The fns extends fns allows us to use distributive conditional types effectively for creating the possible values.

Check out the Playground example here


If you want this approach to work with any function, you can utilize a helper generic function for inference like so:

function makeObj<fn extends (...args: any[]) => any>(obj: {
    listener: fn;
    firstParameter: Parameters<fn>[0];
}) {
    return obj;
}

Then, you can apply this method to any function as demonstrated below:

const o = makeObj({
    listener: (ok: string) => +ok,
    firstParameter: "must be string",
});

Explore the Playground example for more clarity

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

Issue with Resolving Generic Types into Union

The code snippet below is causing errors: class Base { } class Child1 extends Base { child1Fn() {} static deserialize(bytes: Uint8Array): Child1 { return new Child1(); } } class Child2 extends Base { child2Fn() {} static deserialize(bytes ...

What is the correct way to define types for higher-order class components in TypeScript?

I have developed a utility function that currently has an unused options parameter, and it returns a higher-order component wrapping function. How can I effectively define types on the component so that users of the wrapped component can visualize the typ ...

The 'property' is not found within the type '{ my_function(): void; }'

I am just starting out with TypeScript and VueJS. Currently, I am pondering the best approach for setting the type of a JSON key that should start off as null. <script lang="ts"> import Vue from 'vue'; export default Vue. ...

Using TypeScript with Vue allows you to customize the default export of Vue

Currently experimenting with Vue and TypeScript, attempting to compile to AMD in my tsconfig file. The type definition in vue/types/index.d.ts for Vue.js includes: export default Vue; However, this results in TypeScript compiling it like this: import V ...

What is the proper way to create an array of dynamically nested objects in TypeScript?

Consider the structure of an array : [ branch_a: { holidays: [] }, branch_b: { holidays: [] }, ] In this structure, branch_a, branch_b, and ... represent dynamic keys. How can this be properly declared in typescript? Here is an attempt: ty ...

What steps are involved in ensuring that this NodeJS package is compatible with browsers?

My latest pet project was built using nodejs, a technology I chose due to my lack of previous experience with it and my curiosity. Now, I'm looking to modify this package so it can run in a browser and eventually be published on Bower. The npm packag ...

Exploring the Use of ExpressJS Session with Typescript

In my experience with using TypeScript in ExpressJS, I have encountered several issues. One of them involves accessing data in the request and response parameters provided by third-party middleware like express-session. Here is the code snippet that has b ...

What are the steps for compiling TypeScript using Babel 7 CLI?

Here's the issue: When I run 'babel ./src/MyTypescript.ts --out-dir ./wwwroot/js/', I don't get any errors and it just says '0 compiled'. Even though my .babelrc file contains all the necessary configurations for Babel 7 to ...

Using Ionic 3 to create a list view that includes buttons linked to the items clicked

I need assistance with modifying the button icon in a list layout: <ion-list inset *ngFor="let audio of event.audios; let i = index"> <ion-item> <div class="item-text-center item-text-wrap"> {{audio.fileName}} </div& ...

Adding the expiry date/time to the verification email sent by AWS Cognito

After some investigation, I discovered that when a user creates an account on my website using AWS Cognito, the verification code remains valid for 24 hours. Utilizing the AWS CDK to deploy my stacks in the AWS environment, I encountered a challenge within ...

Angular 10: Oops! An issue occurred stating that the mat-form-field needs to have a MatFormFieldControl inside

When attempting to set up a form group on a page, I encountered the following error: ERROR Error: No value accessor for form control with name: 'modalidade' at _throwError (forms.js:2431) at setUpControl (forms.js:2339) at FormGroupDirective.addC ...

Issues arising from an aging Angular project

I'm currently facing an issue with installing node and typescript for an older angular project that I have inherited. This project is using angular 2.4.10 After downloading and installing node version 6.9.5 from the executable file, I proceeded to in ...

What is the method for defining functions that accept two different object types in Typescript?

After encountering the same issue multiple times, I've decided it's time to address it: How can functions that accept two different object types be defined in Typescript? I've referred to https://www.typescriptlang.org/docs/handbook/unions ...

I offer a unique service that creates custom toolbars with a variety of classes to choose from

menu component import { QueryParam } from "./query-param"; import { QueryRouterLink } from "./query-router-link"; export class Menu { link: string; name: string; queryParam: QueryParam[]; queryRouterLink?: QueryRouterLink; } QueryParam class e ...

Understanding how to use TypeScript modules with system exports in the browser using systemjs

I’m facing an issue while using systemjs. I compiled this code with tsc and exported it: https://github.com/quantumjs/solar-popup/blob/master/package.json#L10 { "compilerOptions": { "module": "system", "target": "es5", "sourceMap": true, ...

The NgRX Effect is malfunctioning

Working on integrating ngrx with Angular. Authentication is successful, but facing issues with product store implementation: Organizing the project using modules: const routes: Routes = [ { path: '', redirectTo: 'home', ...

Troubleshooting Next.js 14 JWT Session Error in Conjunction with Next Auth - addressing a type

Recently, I delved into working with Next.js 14 and Next Auth 5 beta. However, every time I attempt to log in, I encounter the following error: [auth][error][JWTSessionError] [auth][cause]: TypeError: Cannot read properties of undefined (reading 'user ...

Tips for incorporating the closeAutocomplete function into ng4-geoautocomplete

Hey there! I've incorporated the ng4-autocomplete component into my custom component and now I'm trying to figure out how to detect when the autocomplete dropdown closes. Can you help me out with implementing the "closeAutocomplete" method? Let& ...

Property undefined with all alert points filled

According to the console, I am facing an issue while trying to route to the dashboard after logging in because the surname property is undefined. However, when I check my alerts, I can see that it is filled correctly at all times. login(surName: string, pa ...

What could be causing this error for my NPM module in a .NET Core project using Typescript?

My Typescript configuration seems to be causing some issues, even though everything works fine without TS. Could the problem lie in my .d.ts file? And do I really need it for webpack? I have a basic NPM module: index.js: var MyMathTS = function(a, b){ ...