Description
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.