Generic type unnarrowed by `switch...case`
See original GitHub issueBug Report
🔎 Search Terms
- narrowing of generic types
- exhaustive switch case
🕗 Version & Regression Information
Theoretically this should be fixed by:
- https://github.com/microsoft/TypeScript/issues/13995
- https://github.com/microsoft/TypeScript/pull/43183
Similar issue:
I’m trying against the latest beta: 4.3.0-pr-43183-11 / 15fae38b39a370f1f597606e552dd40998a1ac49.
⏯ Playground Link
Playground link with relevant code
💻 Code
interface TopLevelElementMap {
"a": HTMLElement;
"b": HTMLElement;
}
interface ElementAttributes {}
interface ElementAttributesMap {
"a": ElementAttributes;
"b": ElementAttributes;
}
class Element<TagName extends keyof TopLevelElementMap> {
protected attributes: ElementAttributesMap[TagName] = {};
public constructor(type: TagName) {}
}
const ElementTagNameMap = {
"a": function(): Element<"a"> {
return new Element("a");
},
"b": function(): Element<"b"> {
return new Element("b");
}
};
function createPrimitive<TagName extends keyof typeof ElementTagNameMap>(tagName: TagName) {
switch (tagName) {
case "a":
return function(): Element<TagName> {
//
// [?] Shouldn't `tagName` get narrowed to just "a"?
//
return ElementTagNameMap[tagName]();
};
case "b":
default:
throw new Error("Unrecognized element `" + tagName + "`.");
}
}
const a = createPrimitive("a");
const b = createPrimitive("b");
As a workaround I can assert as Element<TagName>
on the inner-most return statement to silence the error.
🙁 Actual behavior
Type 'Element<"a"> | Element<"b">' is not assignable to type 'Element<TagName>'.
Type 'Element<"a">' is not assignable to type 'Element<TagName>'.
Type '"a"' is not assignable to type 'TagName'.
'"a"' is assignable to the constraint of type 'TagName', but 'TagName' could be instantiated with a different subtype of constraint '"a" | "b"'. (2322)
🙂 Expected behavior
TagName
should be narrowed to one of the possible values dictated by the case clause.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:4
- Comments:10 (3 by maintainers)
Top Results From Across the Web
Narrowing types using switch statement does not work on a ...
On example 1, I am trying to narrow down a generic type which extends an enum. However it still errors when I use...
Read more >ouuan on Twitter: "我看不懂了... #TypeScript https://t.co ...
Generic type unnarrowed by `switch...case` · Issue #43873 · microsoft/TypeScript. Bug Report Search Terms narrowing of generic types ...
Read more >Determining object type of a Generic Type using the Switch ...
This generic function should be able to take in a generic type and execute code based on the generic type passed into the...
Read more >Variables - Emacs Online Documentation
... bibtex-autokey-name-case-convert · bibtex-autokey-name-change-strings · bibtex-autokey-name- ... cc-imenu-objc-generic-expression-general-func-index ...
Read more >The Org Manual - Org mode
Note that in this case, ' make autoloads ' is mandatory: it defines Org's ... Switch back to the startup visibility of the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Is there a more targeted issue for just this problem?
In case it helps, here’s a simpler situation that demonstrates it without the other problems mentioned by @RyanCavanaugh:
I found a case that could be relevant: Playground link.
I’ve confirmed that in this piece of code,
const a: "a" = x
,takesA(x)
andconst never: never = x
have errors in TypeScript v4.2.3. But in v4.3.5, onlyobj[x]
have an error. This could be the result of #13995 being partially fixed.