Skip to content

Inconsistency in generic parameter inference #38264

Open
@ilogico

Description

@ilogico

TypeScript Version: 3.8.3, nightly, etc.

Search Terms: infer function return

Code

declare function h<T extends keyof HTMLElementTagNameMap>(
    tag: T,
    ...init: ((e: HTMLElementTagNameMap[T]) => void)[],
): HTMLElementTagNameMap[T];

declare function events<T extends HTMLElement>(
    handlers: Partial<{ [K in keyof HTMLElementEventMap]: (this: T, e: HTMLElementEventMap[K]) => void }>
): (e: T) => void;

declare function props<T extends HTMLElement>(
    props: Partial<T>
): (e: T) => void;

h(
    'input',
    events({
        input() {
            this.value;
        },
    }),
    props({
        value: '42'
    })
)

Expected behavior:
no errors
Actual behavior:

    Argument of type '{ value: string; }' is not assignable to parameter of type 'Partial<HTMLElement>'. Object literal may only specify known properties, and 'value' does not exist in type 'Partial<HTMLElement>'.

Playground Link: playground

Related Issues: I'm pretty sure I didn't choose a decent title for the issue, so my ability to search for this is limited as well.

I can understand this could be viewed as feature request/improvement, but there are a couple of reasons that make the behaviour feel buggy:

  1. The inference works correctly for the events call, which is resolved as events<HTMLInputElement>.
  2. The intellisense works on the props argument, which means at some point, the compiler understands I'm writing a Partial<HTMLInputElement>. But for some reason, it resolves the call to props<HTMLElement>, so the code fails to typecheck. I can work around it by adding the type parameter, but it degrades de developing experience.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions