mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-13 23:48:54 -05:00
Merge pull request #31337 from microsoft/fixConditionalTypeParameterReference
Fix type parameter leakage in conditional types
This commit is contained in:
@@ -10482,21 +10482,6 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function isPossiblyReferencedInConditionalType(tp: TypeParameter, node: Node) {
|
||||
if (isTypeParameterPossiblyReferenced(tp, node)) {
|
||||
return true;
|
||||
}
|
||||
while (node) {
|
||||
if (node.kind === SyntaxKind.ConditionalType) {
|
||||
if (isTypeParameterPossiblyReferenced(tp, (<ConditionalTypeNode>node).extendsType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
@@ -10504,7 +10489,7 @@ namespace ts {
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
|
||||
const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
|
||||
const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isPossiblyReferencedInConditionalType(tp, node));
|
||||
const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, node));
|
||||
const root: ConditionalRoot = {
|
||||
node,
|
||||
checkType,
|
||||
@@ -11198,9 +11183,12 @@ namespace ts {
|
||||
// type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
|
||||
if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
|
||||
const container = tp.symbol.declarations[0].parent;
|
||||
if (findAncestor(node, n => n.kind === SyntaxKind.Block ? "quit" : n === container)) {
|
||||
return !!forEachChild(node, containsReference);
|
||||
for (let n = node; n !== container; n = n.parent) {
|
||||
if (!n || n.kind === SyntaxKind.Block || n.kind === SyntaxKind.ConditionalType && forEachChild((<ConditionalTypeNode>n).extendsType, containsReference)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !!forEachChild(node, containsReference);
|
||||
}
|
||||
return true;
|
||||
function containsReference(node: Node): boolean {
|
||||
|
||||
@@ -267,4 +267,10 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repro from #31326
|
||||
|
||||
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
|
||||
type What = Hmm<{}, { a: string }>
|
||||
const w: What = { a: 4 };
|
||||
|
||||
@@ -188,6 +188,12 @@ type ProductComplementComplement = {
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repro from #31326
|
||||
|
||||
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
|
||||
type What = Hmm<{}, { a: string }>
|
||||
const w: What = { a: 4 };
|
||||
|
||||
|
||||
//// [conditionalTypes2.js]
|
||||
@@ -265,6 +271,7 @@ function foo(value) {
|
||||
toString2(value);
|
||||
}
|
||||
}
|
||||
var w = { a: 4 };
|
||||
|
||||
|
||||
//// [conditionalTypes2.d.ts]
|
||||
@@ -392,3 +399,10 @@ declare type ProductComplementComplement = {
|
||||
};
|
||||
declare type PCCA = ProductComplementComplement['a'];
|
||||
declare type PCCB = ProductComplementComplement['b'];
|
||||
declare type Hmm<T, U extends T> = U extends T ? {
|
||||
[K in keyof U]: number;
|
||||
} : never;
|
||||
declare type What = Hmm<{}, {
|
||||
a: string;
|
||||
}>;
|
||||
declare const w: What;
|
||||
|
||||
@@ -685,3 +685,25 @@ type PCCB = ProductComplementComplement['b'];
|
||||
>PCCB : Symbol(PCCB, Decl(conditionalTypes2.ts, 187, 45))
|
||||
>ProductComplementComplement : Symbol(ProductComplementComplement, Decl(conditionalTypes2.ts, 181, 34))
|
||||
|
||||
// Repro from #31326
|
||||
|
||||
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
|
||||
>Hmm : Symbol(Hmm, Decl(conditionalTypes2.ts, 188, 45))
|
||||
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
|
||||
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
|
||||
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
|
||||
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
|
||||
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
|
||||
>K : Symbol(K, Decl(conditionalTypes2.ts, 192, 44))
|
||||
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
|
||||
|
||||
type What = Hmm<{}, { a: string }>
|
||||
>What : Symbol(What, Decl(conditionalTypes2.ts, 192, 76))
|
||||
>Hmm : Symbol(Hmm, Decl(conditionalTypes2.ts, 188, 45))
|
||||
>a : Symbol(a, Decl(conditionalTypes2.ts, 193, 21))
|
||||
|
||||
const w: What = { a: 4 };
|
||||
>w : Symbol(w, Decl(conditionalTypes2.ts, 194, 5))
|
||||
>What : Symbol(What, Decl(conditionalTypes2.ts, 192, 76))
|
||||
>a : Symbol(a, Decl(conditionalTypes2.ts, 194, 17))
|
||||
|
||||
|
||||
@@ -431,3 +431,18 @@ type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
>PCCB : Product<"b", 1>
|
||||
|
||||
// Repro from #31326
|
||||
|
||||
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
|
||||
>Hmm : Hmm<T, U>
|
||||
|
||||
type What = Hmm<{}, { a: string }>
|
||||
>What : { a: number; }
|
||||
>a : string
|
||||
|
||||
const w: What = { a: 4 };
|
||||
>w : { a: number; }
|
||||
>{ a: 4 } : { a: number; }
|
||||
>a : number
|
||||
>4 : 4
|
||||
|
||||
|
||||
@@ -190,3 +190,9 @@ type ProductComplementComplement = {
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repro from #31326
|
||||
|
||||
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
|
||||
type What = Hmm<{}, { a: string }>
|
||||
const w: What = { a: 4 };
|
||||
|
||||
Reference in New Issue
Block a user