Skip to content

Commit 4d15bb1

Browse files
authored
Fix #50869, only cache calculated type for non-context sensitive parameters (#50976)
* Fix #50869, only cache calculated type for non-context sensitive parameters * Simplify check, update comment
1 parent c49c733 commit 4d15bb1

File tree

3 files changed

+162
-2
lines changed

3 files changed

+162
-2
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9746,16 +9746,33 @@ namespace ts {
97469746
}
97479747
}
97489748

9749+
function isParameterOfContextSensitiveSignature(symbol: Symbol) {
9750+
let decl = symbol.valueDeclaration;
9751+
if (!decl) {
9752+
return false;
9753+
}
9754+
if (isBindingElement(decl)) {
9755+
decl = walkUpBindingElementsAndPatterns(decl);
9756+
}
9757+
if (isParameter(decl)) {
9758+
return isContextSensitiveFunctionOrObjectLiteralMethod(decl.parent);
9759+
}
9760+
return false;
9761+
}
9762+
97499763
function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type {
97509764
const links = getSymbolLinks(symbol);
97519765
if (!links.type) {
97529766
const type = getTypeOfVariableOrParameterOrPropertyWorker(symbol);
97539767
// For a contextually typed parameter it is possible that a type has already
97549768
// been assigned (in assignTypeToParameterAndFixTypeParameters), and we want
9755-
// to preserve this type.
9756-
if (!links.type) {
9769+
// to preserve this type. In fact, we need to _prefer_ that type, but it won't
9770+
// be assigned until contextual typing is complete, so we need to defer in
9771+
// cases where contextual typing may take place.
9772+
if (!links.type && !isParameterOfContextSensitiveSignature(symbol)) {
97579773
links.type = type;
97589774
}
9775+
return type;
97599776
}
97609777
return links.type;
97619778
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/completionDetailsOfContextSensitiveParameterNoCrash.ts",
5+
"position": 3101,
6+
"name": ""
7+
},
8+
"quickInfo": {
9+
"kind": "parameter",
10+
"kindModifiers": "",
11+
"textSpan": {
12+
"start": 3101,
13+
"length": 4
14+
},
15+
"displayParts": [
16+
{
17+
"text": "(",
18+
"kind": "punctuation"
19+
},
20+
{
21+
"text": "parameter",
22+
"kind": "text"
23+
},
24+
{
25+
"text": ")",
26+
"kind": "punctuation"
27+
},
28+
{
29+
"text": " ",
30+
"kind": "space"
31+
},
32+
{
33+
"text": "args",
34+
"kind": "parameterName"
35+
},
36+
{
37+
"text": ":",
38+
"kind": "punctuation"
39+
},
40+
{
41+
"text": " ",
42+
"kind": "space"
43+
},
44+
{
45+
"text": "any",
46+
"kind": "keyword"
47+
}
48+
],
49+
"documentation": []
50+
}
51+
}
52+
]
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @strict: true
4+
////type __ = never;
5+
////
6+
////interface CurriedFunction1<T1, R> {
7+
//// (): CurriedFunction1<T1, R>;
8+
//// (t1: T1): R;
9+
////}
10+
////interface CurriedFunction2<T1, T2, R> {
11+
//// (): CurriedFunction2<T1, T2, R>;
12+
//// (t1: T1): CurriedFunction1<T2, R>;
13+
//// (t1: __, t2: T2): CurriedFunction1<T1, R>;
14+
//// (t1: T1, t2: T2): R;
15+
////}
16+
////
17+
////interface CurriedFunction3<T1, T2, T3, R> {
18+
//// (): CurriedFunction3<T1, T2, T3, R>;
19+
//// (t1: T1): CurriedFunction2<T2, T3, R>;
20+
//// (t1: __, t2: T2): CurriedFunction2<T1, T3, R>;
21+
//// (t1: T1, t2: T2): CurriedFunction1<T3, R>;
22+
//// (t1: __, t2: __, t3: T3): CurriedFunction2<T1, T2, R>;
23+
//// (t1: T1, t2: __, t3: T3): CurriedFunction1<T2, R>;
24+
//// (t1: __, t2: T2, t3: T3): CurriedFunction1<T1, R>;
25+
//// (t1: T1, t2: T2, t3: T3): R;
26+
////}
27+
////
28+
////interface CurriedFunction4<T1, T2, T3, T4, R> {
29+
//// (): CurriedFunction4<T1, T2, T3, T4, R>;
30+
//// (t1: T1): CurriedFunction3<T2, T3, T4, R>;
31+
//// (t1: __, t2: T2): CurriedFunction3<T1, T3, T4, R>;
32+
//// (t1: T1, t2: T2): CurriedFunction2<T3, T4, R>;
33+
//// (t1: __, t2: __, t3: T3): CurriedFunction3<T1, T2, T4, R>;
34+
//// (t1: __, t2: __, t3: T3): CurriedFunction2<T2, T4, R>;
35+
//// (t1: __, t2: T2, t3: T3): CurriedFunction2<T1, T4, R>;
36+
//// (t1: T1, t2: T2, t3: T3): CurriedFunction1<T4, R>;
37+
//// (t1: __, t2: __, t3: __, t4: T4): CurriedFunction3<T1, T2, T3, R>;
38+
//// (t1: T1, t2: __, t3: __, t4: T4): CurriedFunction2<T2, T3, R>;
39+
//// (t1: __, t2: T2, t3: __, t4: T4): CurriedFunction2<T1, T3, R>;
40+
//// (t1: __, t2: __, t3: T3, t4: T4): CurriedFunction2<T1, T2, R>;
41+
//// (t1: T1, t2: T2, t3: __, t4: T4): CurriedFunction1<T3, R>;
42+
//// (t1: T1, t2: __, t3: T3, t4: T4): CurriedFunction1<T2, R>;
43+
//// (t1: __, t2: T2, t3: T3, t4: T4): CurriedFunction1<T1, R>;
44+
//// (t1: T1, t2: T2, t3: T3, t4: T4): R;
45+
////}
46+
////
47+
////declare var curry: {
48+
//// <T1, R>(func: (t1: T1) => R, arity?: number): CurriedFunction1<T1, R>;
49+
//// <T1, T2, R>(func: (t1: T1, t2: T2) => R, arity?: number): CurriedFunction2<T1, T2, R>;
50+
//// <T1, T2, T3, R>(func: (t1: T1, t2: T2, t3: T3) => R, arity?: number): CurriedFunction3<T1, T2, T3, R>;
51+
//// <T1, T2, T3, T4, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4) => R, arity?: number): CurriedFunction4<T1, T2, T3, T4, R>;
52+
//// (func: (...args: any[]) => any, arity?: number): (...args: any[]) => any;
53+
//// placeholder: __;
54+
////};
55+
////
56+
////export type StylingFunction = (
57+
//// keys: (string | false | undefined) | (string | false | undefined)[],
58+
//// ...rest: unknown[]
59+
////) => object;
60+
////
61+
////declare const getStylingByKeys: (
62+
//// mergedStyling: object,
63+
//// keys: (string | false | undefined) | (string | false | undefined)[],
64+
//// ...args: unknown[]
65+
////) => object;
66+
////
67+
////declare var mergedStyling: object;
68+
////
69+
////export const createStyling: CurriedFunction3<
70+
//// (base16Theme: object) => unknown,
71+
//// object | undefined,
72+
//// object | undefined,
73+
//// StylingFunction
74+
////> = curry<
75+
//// (base16Theme: object) => unknown,
76+
//// object | undefined,
77+
//// object | undefined,
78+
//// StylingFunction
79+
////>(
80+
//// (
81+
//// getStylingFromBase16: (base16Theme: object) => unknown,
82+
//// options: object = {},
83+
//// themeOrStyling: object = {},
84+
//// ...args
85+
//// ): StylingFunction => {
86+
//// return curry(getStylingByKeys, 2)(mergedStyling, .../**/args);
87+
//// },
88+
//// 3
89+
////);
90+
91+
verify.baselineQuickInfo();

0 commit comments

Comments
 (0)