Type union narrowing upon index access #56943
Labels
Suggestion
An idea for TypeScript
Too Complex
An issue which adding support for may be too complex for the value it adds
🔍 Search Terms
"type union narrowing on multiple properties", "type dependencies", "narrowing indexed", "narrowing argument"
✅ Viability Checklist
⭐ Suggestion
Notice: It’s likely this request has been raised before and I wasn’t using the right search terms. Apologies in advance.
Using type unions and dynamic property access extensively, I have come across the following situation a few times already: There is a discriminating element in the type union that could be used to index a different type that references the corresponding union component. TypeScript could know whether the result from the property access and the union type are structurally related and allow the access. However, as it stands, it needs a little help in form of an explicit conditional (see example below).
📃 Motivating Example
https://www.typescriptlang.org/play?ts=5.3.2#code/JYOwLgpgTgZghgYwgAgPICMBWyDeAoZZOALmQGcwpQBzAbgOXVJAFcBbdaewsiMAQQAUJcpRoBKUgDcA9sAAm3cnwBCgpslYdok5LIX0AvnjABPAA4oACjLJlg6ADYR+CJHZlQyyALwMAPrjmUDLmpADkcOEANHpwjiwQpBRUINSxvGCQUBGZ-OHGhIE4waER6DFxCUma7JxQGXzZuaoF9HgwLCAIYMAyIMpgViHmgjJYpBiYsWCkNnYOzq7uZJ5k4rgMwDCCYAB0pea+Pj7IkeEb+ISE45gA2vuHALq+yPtS8YlKhsgQjryba7IW4PA4jF6nd6fCDfPDGTrdXr9QbLCAeKBjCZoLAzOa2exOFxuNGrLyXLY7R4jY6nc7koEg-aZbJPXZ7D7VcTfX7-FBXa6MvbM6CsqGc2HGPBAA
In this example, the
if
…else
constructs in the functionssetProp
andsetAccessor
are entirely superfluous but currently required for successful compilation.As it stands, with every component added to the
PossibleAccessors
union, a new control flow branch has to be added to get the code to compile without type casting.💻 Use Cases
Currently, I resort to type casting in these situations and I enforce conformability between the unions and the corresponding properties using an intricate set of conditional types. This is brittle as there is no nothing informing me when I have set these types up incorrectly. Even when it works, it makes the compile error happen at a location very different from where the run-time error would be.
It would be a tremendous help if TypeScript could narrow the property access correctly without the user having to insert superfluous constructs.
I.e., the following code should just compile™: https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&allowUnreachableCode=true&allowUnusedLabels=true&exactOptionalPropertyTypes=true&noFallthroughCasesInSwitch=true&noImplicitOverride=true&noPropertyAccessFromIndexSignature=true&ts=5.3.2#code/JYOwLgpgTgZghgYwgAgPICMBWyDeAoZZOALmQGcwpQBzAbgOXVJAFcBbdaewsiMAQQAUJcpRoBKUgDcA9sAAm3cnwBCgpslYdok5LIVLqfIbopUQdBkbBrdWzlHoBfPGACeABxQAFGWTLA6AA2EPwISP4yUGTIALwMAD64HlAyHqQA5HAZADR6cEEsEKRmNHm8YJBQmRX8ucjWVZnWdS6ESTgpaZno9VIFRczsDuV8TcgZFSr1jdDNqhlO9HgwLCAIYMAyIMpg3qkegjJYpBiYeWCkvv6BIWERZFFk4rgMx5gA2mAAdF0eALpxZA-fqFCDOFZrDZbHa1cIQSJQI4nNBYC5XPwBYKheGI56vQjvL7fCpVf6CEEDCDiCFAA
The text was updated successfully, but these errors were encountered: