Merge pull request #23067 from Microsoft/fixTPReferenceInConditional

Fix type parameter reference checks in conditional types
This commit is contained in:
Anders Hejlsberg 2018-04-02 17:30:32 -07:00 committed by GitHub
commit 751eab9eed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 233 additions and 6 deletions

View File

@ -8466,15 +8466,19 @@ namespace ts {
return result;
}
function getTopConditionalType(node: Node): ConditionalTypeNode {
let result: ConditionalTypeNode;
function isPossiblyReferencedInConditionalType(tp: TypeParameter, node: Node) {
if (isTypeParameterPossiblyReferenced(tp, node)) {
return true;
}
while (node) {
if (node.kind === SyntaxKind.ConditionalType) {
result = <ConditionalTypeNode>node;
if (isTypeParameterPossiblyReferenced(tp, (<ConditionalTypeNode>node).extendsType)) {
return true;
}
}
node = node.parent;
}
return result;
return false;
}
function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type {
@ -8483,8 +8487,7 @@ namespace ts {
const checkType = getTypeFromTypeNode(node.checkType);
const aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node);
const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
const topNode = getTopConditionalType(node);
const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, topNode));
const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isPossiblyReferencedInConditionalType(tp, node));
const root: ConditionalRoot = {
node,
checkType,

View File

@ -176,4 +176,19 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
toString2(value);
}
}
// Repro from #23052
type A<T, V, E> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A<T[Q], V, E>; }
: T extends V ? T : never;
type B<T, V> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B<T[Q], V>; }
: T extends V ? T : never;
type C<T, V, E> =
{ [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C<T[Q], V, E>; };

View File

@ -119,6 +119,21 @@ function foo<T>(value: T) {
toString2(value);
}
}
// Repro from #23052
type A<T, V, E> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A<T[Q], V, E>; }
: T extends V ? T : never;
type B<T, V> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B<T[Q], V>; }
: T extends V ? T : never;
type C<T, V, E> =
{ [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C<T[Q], V, E>; };
//// [conditionalTypes2.js]
@ -254,3 +269,18 @@ interface B1<T> extends A1<T> {
declare function toString1(value: object | Function): string;
declare function toString2(value: Function): string;
declare function foo<T>(value: T): void;
declare type A<T, V, E> = T extends object ? {
[Q in {
[P in keyof T]: T[P] extends V ? P : P;
}[keyof T]]: A<T[Q], V, E>;
} : T extends V ? T : never;
declare type B<T, V> = T extends object ? {
[Q in {
[P in keyof T]: T[P] extends V ? P : P;
}[keyof T]]: B<T[Q], V>;
} : T extends V ? T : never;
declare type C<T, V, E> = {
[Q in {
[P in keyof T]: T[P] extends V ? P : P;
}[keyof T]]: C<T[Q], V, E>;
};

View File

@ -414,3 +414,85 @@ function foo<T>(value: T) {
}
}
// Repro from #23052
type A<T, V, E> =
>A : Symbol(A, Decl(conditionalTypes2.ts, 119, 1))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9))
>E : Symbol(E, Decl(conditionalTypes2.ts, 123, 12))
T extends object
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A<T[Q], V, E>; }
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 125, 9))
>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17))
>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9))
>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17))
>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>A : Symbol(A, Decl(conditionalTypes2.ts, 119, 1))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 125, 9))
>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9))
>E : Symbol(E, Decl(conditionalTypes2.ts, 123, 12))
: T extends V ? T : never;
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9))
>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7))
type B<T, V> =
>B : Symbol(B, Decl(conditionalTypes2.ts, 126, 30))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9))
T extends object
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B<T[Q], V>; }
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 130, 9))
>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17))
>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9))
>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17))
>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>B : Symbol(B, Decl(conditionalTypes2.ts, 126, 30))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 130, 9))
>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9))
: T extends V ? T : never;
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9))
>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7))
type C<T, V, E> =
>C : Symbol(C, Decl(conditionalTypes2.ts, 131, 30))
>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7))
>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9))
>E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12))
{ [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C<T[Q], V, E>; };
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 134, 5))
>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13))
>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7))
>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7))
>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13))
>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9))
>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13))
>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13))
>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7))
>C : Symbol(C, Decl(conditionalTypes2.ts, 131, 30))
>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7))
>Q : Symbol(Q, Decl(conditionalTypes2.ts, 134, 5))
>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9))
>E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12))

View File

@ -444,3 +444,85 @@ function foo<T>(value: T) {
}
}
// Repro from #23052
type A<T, V, E> =
>A : A<T, V, E>
>T : T
>V : V
>E : E
T extends object
>T : T
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A<T[Q], V, E>; }
>Q : Q
>P : P
>T : T
>T : T
>P : P
>V : V
>P : P
>P : P
>T : T
>A : A<T, V, E>
>T : T
>Q : Q
>V : V
>E : E
: T extends V ? T : never;
>T : T
>V : V
>T : T
type B<T, V> =
>B : B<T, V>
>T : T
>V : V
T extends object
>T : T
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B<T[Q], V>; }
>Q : Q
>P : P
>T : T
>T : T
>P : P
>V : V
>P : P
>P : P
>T : T
>B : B<T, V>
>T : T
>Q : Q
>V : V
: T extends V ? T : never;
>T : T
>V : V
>T : T
type C<T, V, E> =
>C : C<T, V, E>
>T : T
>V : V
>E : E
{ [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C<T[Q], V, E>; };
>Q : Q
>P : P
>T : T
>T : T
>P : P
>V : V
>P : P
>P : P
>T : T
>C : C<T, V, E>
>T : T
>Q : Q
>V : V
>E : E

View File

@ -121,3 +121,18 @@ function foo<T>(value: T) {
toString2(value);
}
}
// Repro from #23052
type A<T, V, E> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A<T[Q], V, E>; }
: T extends V ? T : never;
type B<T, V> =
T extends object
? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B<T[Q], V>; }
: T extends V ? T : never;
type C<T, V, E> =
{ [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C<T[Q], V, E>; };