You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Can't dereference array type in conditional type #22985
T[P][0] is usable and doesn't produce an error, since T[P] extends any[] and should thus be indexable on [0] (it seems this is the way to dereference an array)
Actual behavior:
I am getting type 0 cannot be used to index type T[P].
The odd part is that behaviour-wise it seems to be working ! I can't change the type of the nested c to anything other than string and I can't create random properties or what.
The compiler does not recognize the constraints on anything that is not a naked type parameter in a conditional type in the true branch. so T[P] extends any[] does not narrow T[P] to array in the true branch. there are two ways to accomplish that, either use infer as Ryan Cavanaugh (@RyanCavanaugh) noted. the other is to just move it to a diffrent type alias declaration:
The compiler does not recognize the constraints on anything that is not a naked type parameter in a conditional type in the true branch.
Actually I think Anders Hejlsberg (@ahejlsberg) just recently changed it (#22707) so we manufacture constraints for indexes and matching tuples, too. We should have it constrained here, afaik.
It's a bug. The issue here is that we use isPartOfTypeNode in the parent node walk that attaches synthetic constraints to type variables, but isPartOfTypeNode returns false for property and parameter declarations so we end up stopping prematurely. I will fix to use some other stopping condition.
Christophe Eymard (@ceymard) With the fix your example now compiles. That said, I'd suggest refactoring the conditional type inside the mapped type into a separate type alias:
This type is distributive (because it operates on a naked type parameter) which ensures that the operation spreads itself over union types (e.g. RecursivePartialItem<Foo | undefined> becomes RecursivePartalItem<Foo> | RecursivePartialItem<undefined>). Without this change, your example will do nothing to properties with union types (such as optional properties). Read more about distributive conditional types here #21316 (comment).
Activity
RyanCavanaugh commentedon Mar 29, 2018
Not sure why that's not allowed. Anders Hejlsberg (@ahejlsberg) / Wesley Wigham (@weswigham) ?
FWIW I would write it this way:
mhegazy commentedon Mar 29, 2018
The compiler does not recognize the constraints on anything that is not a naked type parameter in a conditional type in the true branch. so
T[P] extends any[]does not narrowT[P]to array in the true branch. there are two ways to accomplish that, either useinferas Ryan Cavanaugh (@RyanCavanaugh) noted. the other is to just move it to a diffrent type alias declaration:mhegazy commentedon Mar 29, 2018
We probably should rethink our design choices here. it is confusing that
T[P] extends Udoes not work likeT extends U.weswigham commentedon Mar 29, 2018
Actually I think Anders Hejlsberg (@ahejlsberg) just recently changed it (#22707) so we manufacture constraints for indexes and matching tuples, too. We should have it constrained here, afaik.
ahejlsberg commentedon Mar 29, 2018
It's a bug. The issue here is that we use
isPartOfTypeNodein the parent node walk that attaches synthetic constraints to type variables, butisPartOfTypeNodereturns false for property and parameter declarations so we end up stopping prematurely. I will fix to use some other stopping condition.ahejlsberg commentedon Mar 29, 2018
Christophe Eymard (@ceymard) With the fix your example now compiles. That said, I'd suggest refactoring the conditional type inside the mapped type into a separate type alias:
This type is distributive (because it operates on a naked type parameter) which ensures that the operation spreads itself over union types (e.g.
RecursivePartialItem<Foo | undefined>becomesRecursivePartalItem<Foo> | RecursivePartialItem<undefined>). Without this change, your example will do nothing to properties with union types (such as optional properties). Read more about distributive conditional types here #21316 (comment).sirian commentedon Mar 29, 2018
Christophe Eymard (@ceymard) try infer T[P] like this