Skip to content

create dynamic function with Generic Map per item is not identifying the return value and think it an error. #43922

Closed
@nisimjoseph

Description

@nisimjoseph

Bug Report

When implementing function like document.createElement which implementing signature like
createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K]; will bring an error for each return value, but when doing ts-ignore to all return values it will show the correct value when it interpater the return value while using the method.

example code below and can play here.

const enum ActionList {
    Move = "move",
    Jump = "jump",
    Sit = "sit",
}

interface Action {
    [ActionList.Move]:number;
    [ActionList.Jump]:string;
    [ActionList.Sit]:boolean;
}

function callAction<K extends keyof Action>(action:K):Action[K] {
    switch (action) {
        case ActionList.Move: return 100;     // Show error: Type 'number' is not assignable to type 'never'
        case ActionList.Jump: return "100"; // Show error: Type 'string' is not assignable to type 'never'
        case ActionList.Move: return true;    // Show error: Type 'boolean' is not assignable to type 'never'
    }
    return undefined;   // Show error: Type 'undefined' is not assignable to type 'never'
}

callAction(ActionList.Move);
callAction(ActionList.Jump);
callAction(ActionList.Sit);

As you can see in the link here the compiler think we have an error in the return types, it thinks the return type suppose to be number & string & boolean for each return value, but the functions call signature which using the callAction method show the correct value per type we pass inside.

for now, to fix it I did // @ts-ignore for each return value and the compiler leave it, but I think this is an error understanding the code.

I might do something wrong, so please tell me if I missed something here.

thank you.

🔎 Search Terms

search terms: createElement generic type, dynamic generic type return map
I found some related things, but nothing I needed. found this issue which is not what I search for, but similar.

🕗 Version & Regression Information

Using TS 4.2.4

I tested it with TS 3.x, 4.x, 4.3 beta. it reproduces on all of them.
using the Playground link to try in multiple versions.

⏯ Playground Link

Playground link with relevant code

💻 Code

const enum ActionList {
    Move = "move",
    Jump = "jump",
    Sit = "sit",
}

interface Action {
    [ActionList.Move]:number;
    [ActionList.Jump]:string;
    [ActionList.Sit]:boolean;
}

function callAction<K extends keyof Action>(action:K):Action[K] {
    switch (action) {
        case ActionList.Move: return 100;     // Show error: Type 'number' is not assignable to type 'never'
        case ActionList.Jump: return "100"; // Show error: Type 'string' is not assignable to type 'never'
        case ActionList.Move: return true;    // Show error: Type 'boolean' is not assignable to type 'never'
    }
    return undefined;   // Show error: Type 'undefined' is not assignable to type 'never'
}

callAction(ActionList.Move);
callAction(ActionList.Jump);
callAction(ActionList.Sit);

🙁 Actual behavior

errors on return types which think each return value needs to be all types together.

🙂 Expected behavior

understand the implementation function return types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions