Leveraging enums within strictFunctionTypes for Typescript generics

Here is a code snippet (TS playground link):

const enum Enum { A, B, C }
  
interface Args {
  e: Enum.A;
}

interface GenericClass<A> {
  new (args: A) : void;
}

class TestClass {
  constructor(args: Args) {}
}

function func<A>(C: GenericClass<A>, args: A) {
  return new C(args);
}

func(TestClass, { e: Enum.A });

The final line [1] triggers an error when strictFunctionTypes is enabled:

Argument of type 'typeof TestClass' is not assignable to parameter of type 'GenericClass<{ e: Enum; }>'.
  Types of parameters 'args' and 'args' are incompatible.
    Type '{ e: Enum; }' is not assignable to type 'Args'.
      Types of property 'e' are incompatible.
        Type 'Enum' is not assignable to type 'Enum.A'.

This is perplexing as I am accepting the exact enum value Enum.A and passing the same value Enum.A into the function.

I understand that I can use type casting like { e: <Enum.A>Enum.A }, but it seems awkward. Is there a way to resolve this issue without resorting to type casting?

Answer №1

There is some uncertainty regarding why this issue occurs, but my belief is that during the inference of A, the compiler considers all instances where A is present and determines the widest possible type to be { e:Enum}. This decision is based on the observation that object literals typically do not infer literal types for their fields. Subsequently, upon further inspection, it realizes that the type is incompatible with the class under strict functions. In accordance with this conjecture, diminishing the priority of the second inference site could yield the correct type for A. This can be achieved through the use of an intersection type A&{} (although I cannot pinpoint the exact source, I recall encountering this solution in a GitHub issue where a member of the compiler team suggested that reducing inference priority in this manner may prove effective in the foreseeable future).

While largely speculative, the proposed solution has proven effective:

const enum Enum { A, B, C }

interface Args {
  e: Enum.A;
}

interface GenericClass<A> {
  new (args: A) : void;
}

class TestClass {
  constructor(args: Args) {}
}


function func<A>(C: GenericClass<A>, args: A & {}) {
  return new C(args);
}

func(TestClass, { e: Enum.A });

playground link

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

Is it possible to verify if a function is invoked using Jest, Typescript, and ts-jest in action?

Currently, I'm testing the functionality of this code snippet: src/helpers/CommentHelper.ts: export default class CommentHelper { gitApiObject: GitApi.IGitApi ; constructor(gitApiObject: GitApi.IGitApi) { this.gitApiObject = gi ...

What is preventing me from completing this specific task in Kotlin?

In my current project, I have implemented the MVI pattern and created both State and Event classes. Within the viewModel, I have a private property called _event of type MutableLiveData, which I then expose to the Activity as a LiveData using the following ...

Including a Javascript library (jsencrypt) in an Angular 2 application

I have gone through countless tutorials on this particular issue, but unfortunately, I have not yet found a solution. Let me provide some context first. I am working on an Angular 2 application and I need to incorporate this JS library for encryption: http ...

Having trouble managing TypeScript in conjunction with React and Redux

As a newcomer to TypeScript, I find myself struggling to grasp the concepts and know where to start or stop. While there are abundant resources available online, I have not been able to effectively utilize them in my project. I am hopeful for some guidance ...

Guide to upgrading ag-grid-community from 20.1.0 to 24.1.0

I'm currently encountering some errors that I can't seem to find in the AgGrid documentation. These attributes are not mentioned anywhere, not even in the Change Log. First off, these compilation errors are popping up: ERROR in : Can't bind ...

Is it possible to specify the version of a dependency using Stackblitz?

Is it possible to specify the dependency version on StackBlitz? I recently updated the dependency on NPM, however StackBlitz seems to be stuck on installing the old version. ...

Troubleshooting: HTTP client post request working with body.set but not with formData.append for sending data to API

I am in the process of updating the UX for an older application with APIs developed in ASP.NET When I make a POST request as shown below, everything works perfectly. The data is received: var APIURL = sessionStorage.getItem('endpoint') + "/ ...

What is the best approach to incorporate Column Reordering in react-data-grid?

Within my REACT application, I have incorporated the npm package react-data-grid. They offer a sample showcasing Column Reordering on their website. I wish to replicate this functionality in my own code. Upon reviewing their source code, I am puzzled abou ...

The information retrieved from the API is not appearing as expected within the Angular 9 ABP framework

I am facing an issue with populating data in my select control, which is located in the header child component. The data comes from an API, but for some reason, it is not displaying correctly. https://i.stack.imgur.com/6JMzn.png. ngOnInit() { thi ...

Webpack compatibility issue hindering big.js node module functionality

I'm currently working on compiling (typescript files) and bundling my source code using webpack. Below is the content of my webpack.config.js file: const path = require('path') module.exports = { devtool: 'eval-source-map', en ...

Adjust the column count in mat-grid-list upon the initial loading of the component

My goal is to implement a mat-grid-list of images with a dynamic number of columns based on the screen size. Everything works perfectly except for one small glitch – when the grid first loads, it defaults to 3 columns regardless of the screen size until ...

How to Utilize an Array from Observable Object in Angular 2 with ngFor and Async Pipe

I am currently learning about the utilization of Observables in Angular 2. Here is a snippet of code from a service I am working with: import {Injectable, EventEmitter, ViewChild} from '@angular/core'; import {Observable} from "rxjs/Observab ...

Tips on how to showcase it to cover a wide area

I'm having trouble figuring out how to display the output in a span element. Every time I try, I just get a blank result, and when I alert the txtNumber variable, I see "object html span element" in the alert message. <span id="displayQty"> num ...

Issues with Webpack and TypeScript CommonsChunkPlugin functionality not functioning as expected

Despite following various tutorials on setting up CommonsChunkPlugin, I am unable to get it to work. I have also gone through the existing posts related to this issue without any success. In my project, I have three TypeScript files that require the same ...

Transform array sequences into their own unique sequences

Reorder Array of List to Fit My Custom Order Current Output: [ { "key": "DG Power Output", "value": "6.00", "unit": "kWh", }, { "key": "DG Run Time", "value": "5999999952", "unit": "minutes", }, { "key": "Fuel Level (Before)", "value": "8.00" ...

Tips on changing the color of a dropdown select option in Angular 8

I have been experimenting with changing the color of a dropdown select menu based on the value selected by the user. Here is the code I have been working with: App.component.ts @Component({ selector: 'my-app', templateUrl: './app.comp ...

Unable to retrieve this information using $http callback

I am currently working with angular 1.5 and typescript, but I am facing an issue where I cannot access the 'this' property from the callback returned by the $http promise. Whenever I try to access a private method from the callback, 'this&a ...

ESLint refuses to be turned off for a particular file

I am in the process of creating a Notes.ts file specifically for TypeScript notes. I require syntax highlighting but do not want to use eslint. How can I prevent eslint from running on my notes file? Directory Structure root/.eslintignore root/NestJS.ts r ...

Angular 7 ESRI loader search widget focus out bug: finding a solution

I am currently working on implementing an ESRI map using esri-loader in my Angular application. Everything seems to be working fine, but I am encountering an error when typing something into the search widget and then focusing out of it. "Uncaught Typ ...

Karma Jasmin is puzzled as to why her tests are failing intermittently, despite the absence of any actual test cases

In this snippet, you will find my oninit method which I am instructed not to modify. ngOnInit(): void { this.setCustomizedValues(); this.sub = PubSub.subscribe('highlightEntity', (subId, entityIdentifier: string) => { ...