Is it possible to dynamically adjust the selectivity of function parameters?

// To start with, I aim to adjust the selectivity of the current function parameter based on a specific generic parameter type mentioned previously. My idea involves utilizing parameter sets and tuples.

// However, implementing parameter sets to dynamically set optional parameters leads to various abnormalities.

// For the sake of simplicity, I have created a basic example below:

interface Options<I> {
  init?: I,
  getInit?: () => I
}

function fun1 <P>(par: P) {
  function fun2 <I, O extends P extends boolean ? [options: Options<I>] : [options?: Options<I>]>(...arg: O) {
    return {
      p: '' as P,
      i: '' as I
    }
  }

  return fun2
}

// My initial concern: Generic type I remains unknown.

// Another issue arises with the lack of mutual constraint between the type of init and the return type of getInit. This appears to be connected to the first problem.

const { p, i } = fun1(true)({
  init: "1",
  getInit: () => "1"
})

How can I address these abnormalities, or are there alternative methods to dynamically set optional function parameters?


For the second revision:

After some experimentation, I have devised certain solutions to the existing issues. However, potential side effects are yet to be determined. I am documenting these for reference.

The provided example lacked the utilization of the generic parameter O. The subsequent example incorporates O and accurately determines its input content.

function fun1<P>(par: P) {
  function fun2<I, O extends Options<I>>(
    ...arg: P extends boolean
        ? [options: Options<I> & O]
        : [options?: Options<I> & O]
  ) {
    return {
      p: '' as P,
      i: '' as I,
      g: '' as unknown as O extends { getInit: () => any } ? true : false
    }
  }

  return fun2
}

const { p, i, g } = fun1(true)({
  init: "1",
  getInit: () => "1"
})
// p boolean
// i string
// g true

Answer №1

There is no need for the generic parameter O in this context. If you are not using a generic type anywhere except for its inference site, then it does not need to be generic.

The following code snippet is equivalent:

function fun1<P>(par: P) {
  function fun2<I>(
    ...arg:
      P extends boolean
        ? [options: Options<I>]
        : [options?: Options<I>]
  ) {
    return {
      p: '' as P,
      i: '' as I
    }
  }

  return fun2
}

By allowing I to be inferred, it can be determined accurately and easily:

const { p, i } = fun1(true)({
  init: "1",
  getInit: () => "1"
})

i // type: string

The I generic is necessary because it is used in the return type.

View playground


As for why, it's hard to explain. Just know that reducing the number of generic parameters, especially when they are interdependent, generally helps in avoiding confusion for the type checker.

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

Encountering an issue while developing a Discord bot using TypeScript

Hello, I'm currently working on creating a nick command for my discord bot in TypeScript, but I encountered an error. Here is the issue: Error: Expression expected.ts (1109) When I replace const mentionedMember = message? message.mentions.members? ...

Is it possible to utilize an npm package in TypeScript without a d.ts definition file?

Is it possible to use an npm package in TypeScript and Node.js without a .d.ts definition file? If so, how can I make it work? Currently, my code looks like this and I'm getting an error that says "cannot find module 'node-rest-client'" bec ...

Determining the appropriate generic type in Typescript

In my code, there is a method designed to extend an existing key-value map with objects of the same type. This can be useful when working with database query results. export function extendWith< T extends { id: string | number }, O = | (T[" ...

filter failing to provide output

Issue with fetching partnername from the filter function, always returning undefined. administrationList = [ { "runid": 6, "partnerid": 2, "partnername": "test admin2", }, { "runid& ...

Is it possible to loop through a subset of a collection using *ngFor?

Is it possible to iterate through a specific range of elements in a collection using *ngFor? For instance, I have a group of checkboxes with their form control name and label specified as follows: [{id: 'c1', label: 'C1'}, ...] Assum ...

Is there a deeper philosophical rationale behind choosing to use (or not use) enums in TypeScript, along with string union types?

Recently, I delved into the world of enum and const enum in Typescript, causing some confusion. I grasped that const enum gets transpiled into simple values while regular enums do not. I also recognized certain distinctions between using string union type ...

Importing components with local data within an ngFor in Angular TypeScript

Having recently started working with Angular2, I am facing a challenge with importing components in ngFor loops. The issue seems to arise when importing components with data in ngFor loops; it checks for values in the .ts file instead of the local variabl ...

What is the best way to run a scheduled task automatically using node-cron?

I have a custom function that saves data to the database using the POST method. When testing it with Postman, I send an empty POST request to trigger the controller. Upon execution, the function triggers two more functions. One of them is responsible for ...

What is the best method for transforming an object into an interface without prior knowledge of the keys

I am looking for a solution to convert a JSON into a TypeScript object. Here is an example of the JSON data: { "key1": { "a": "b" }, "key2": { "a": "c" } } The keys key1 and key2 a ...

Attempting to create a universal logger factory using a functional approach

After reading Martin Fowler's blog on domain oriented observability, I was inspired to implement this concept without relying on classes. However, I encountered some challenges involving generics in TypeScript. Here is the snippet of my code (the erro ...

Tips for updating the display after making an angular $http request using rxjs Observables

I have a project where I am utilizing angular's $http service to fetch data from a remote endpoint. I am keen on incorporating rxjs Observables, hence the call in my service is structured as follows: userInfo() : Rx.Observable<IUserInfo> { ...

Blending ASP.NET Core 2.0 Razor with Angular 4 for a Dynamic Web Experience

I am currently running an application on ASP.NET Core 2.0 with the Razor Engine (.cshtml) and I am interested in integrating Angular 4 to improve data binding from AJAX calls, moving away from traditional jQuery methods. What are the necessary steps I need ...

Extract a string value from a TypeScript enum

Here is a basic enum definition: export enum Type { TEST_ONE = "testing.one", TEST_TWO = "testing.two", BETA = "beta.one" } I am looking to run a function for each string value in the enum. For example: executeType(type: string) { console.lo ...

CreateAsyncModule using an import statement from a variable

When trying to load a component using defineAsyncComponent, the component name that should be rendered is retrieved from the backend. I have created a function specifically for loading the component. const defineAsyncComponentByName = (componentName: strin ...

Utilizing Angular 2's NgFor directive in SVG Elements

I want to use ngFor to draw an SVG Element that consists of lines. I am struggling with the implementation and need some help fixing the code. Here is what I have so far: my-component.js: import {Component} from 'angular2/core'; @Component({ ...

Triggering a class in Angular when another class is activated through JavaScript

My goal is to apply the class "xyz" when the class "xy" is activated using ngClass. I am looking to achieve the following scenario: If the class "xyz" is present in the tag, then activate the class "xy" Using ngClass="'xyz', 'xy'" ...

What are the steps to integrate jQuery into an Angular 8 application?

I am currently working on an application that relies on SignalR for communication with a desktop application. In order to make use of SignalR, I include jQuery in my .ts file. However, after migrating from Angular 7 to Angular 8, it appears that this setup ...

A peculiar TypeError occurred when testing a React component with Enzyme, preventing the addition of a property as the object is not extensible in the Object

Encountered a peculiar issue during testing where I am trying to merge two objects to use as the style of a component, replicating the component's logic with the code provided below. var styles = { "height": 20 } var expectedStyles = (Object as any). ...

Displaying an error message following the dynamic retrieval of the input field's value

How can I display an error message when a specific field with a value of 0 is not filled out in my Angular reactive forms? In my form, I have added a dropdown which is mandatory and I have implemented validators to ensure it is required. The validator work ...

What's the issue with conducting a unit test on a component that has dependencies with further dependencies?

I am experiencing an annoying error that seems to be my mistake and I cannot figure out how to resolve it. The issue lies within a simple component which serves as a top-bar element in my web application. This component has only one dependency, the UserSe ...