Skip to content

Commit 3b49ce9

Browse files
authored
Fixed contravariant inferences from annotated optional parameters (#55397)
1 parent fa9cf2a commit 3b49ce9

7 files changed

+182
-1
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35528,7 +35528,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3552835528
if (declaration.type) {
3552935529
const typeNode = getEffectiveTypeAnnotationNode(declaration);
3553035530
if (typeNode) {
35531-
inferTypes(inferenceContext.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
35531+
const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration));
35532+
const target = getTypeAtPosition(context, i);
35533+
inferTypes(inferenceContext.inferences, source, target);
3553235534
}
3553335535
}
3553435536
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [tests/cases/compiler/contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts] ////
2+
3+
=== contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts ===
4+
// repro https://github.com/microsoft/TypeScript/issues/55394
5+
6+
declare function filter<T>(predicate: (value: T, index: number) => boolean): T;
7+
>filter : Symbol(filter, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 0, 0))
8+
>T : Symbol(T, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 24))
9+
>predicate : Symbol(predicate, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 27))
10+
>value : Symbol(value, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 39))
11+
>T : Symbol(T, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 24))
12+
>index : Symbol(index, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 48))
13+
>T : Symbol(T, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 2, 24))
14+
15+
const a = filter((pose?: number) => true);
16+
>a : Symbol(a, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 3, 5))
17+
>filter : Symbol(filter, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 0, 0))
18+
>pose : Symbol(pose, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 3, 18))
19+
20+
const b = filter((pose?: number, _?: number) => true);
21+
>b : Symbol(b, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 4, 5))
22+
>filter : Symbol(filter, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 0, 0))
23+
>pose : Symbol(pose, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 4, 18))
24+
>_ : Symbol(_, Decl(contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts, 4, 32))
25+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/compiler/contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts] ////
2+
3+
=== contravariantOnlyInferenceWithAnnotatedOptionalParameter.ts ===
4+
// repro https://github.com/microsoft/TypeScript/issues/55394
5+
6+
declare function filter<T>(predicate: (value: T, index: number) => boolean): T;
7+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
8+
>predicate : (value: T, index: number) => boolean
9+
>value : T
10+
>index : number
11+
12+
const a = filter((pose?: number) => true);
13+
>a : number | undefined
14+
>filter((pose?: number) => true) : number | undefined
15+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
16+
>(pose?: number) => true : (pose?: number) => true
17+
>pose : number | undefined
18+
>true : true
19+
20+
const b = filter((pose?: number, _?: number) => true);
21+
>b : number | undefined
22+
>filter((pose?: number, _?: number) => true) : number | undefined
23+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
24+
>(pose?: number, _?: number) => true : (pose?: number, _?: number) => true
25+
>pose : number | undefined
26+
>_ : number | undefined
27+
>true : true
28+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [tests/cases/compiler/contravariantOnlyInferenceWithAnnotatedOptionalParameterJs.ts] ////
2+
3+
=== index.js ===
4+
/**
5+
* @template T
6+
* @param {(value: T, index: number) => boolean} predicate
7+
* @returns {T}
8+
*/
9+
function filter(predicate) {
10+
>filter : Symbol(filter, Decl(index.js, 0, 0))
11+
>predicate : Symbol(predicate, Decl(index.js, 5, 16))
12+
13+
return /** @type {any} */ (null);
14+
}
15+
16+
const a = filter(
17+
>a : Symbol(a, Decl(index.js, 9, 5))
18+
>filter : Symbol(filter, Decl(index.js, 0, 0))
19+
20+
/**
21+
* @param {number} [pose]
22+
*/
23+
(pose) => true
24+
>pose : Symbol(pose, Decl(index.js, 13, 3))
25+
26+
);
27+
28+
const b = filter(
29+
>b : Symbol(b, Decl(index.js, 16, 5))
30+
>filter : Symbol(filter, Decl(index.js, 0, 0))
31+
32+
/**
33+
* @param {number} [pose]
34+
* @param {number} [_]
35+
*/
36+
(pose, _) => true
37+
>pose : Symbol(pose, Decl(index.js, 21, 3))
38+
>_ : Symbol(_, Decl(index.js, 21, 8))
39+
40+
);
41+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [tests/cases/compiler/contravariantOnlyInferenceWithAnnotatedOptionalParameterJs.ts] ////
2+
3+
=== index.js ===
4+
/**
5+
* @template T
6+
* @param {(value: T, index: number) => boolean} predicate
7+
* @returns {T}
8+
*/
9+
function filter(predicate) {
10+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
11+
>predicate : (value: T, index: number) => boolean
12+
13+
return /** @type {any} */ (null);
14+
>(null) : any
15+
}
16+
17+
const a = filter(
18+
>a : number | undefined
19+
>filter( /** * @param {number} [pose] */ (pose) => true) : number | undefined
20+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
21+
22+
/**
23+
* @param {number} [pose]
24+
*/
25+
(pose) => true
26+
>(pose) => true : (pose?: number | undefined) => true
27+
>pose : number | undefined
28+
>true : true
29+
30+
);
31+
32+
const b = filter(
33+
>b : number | undefined
34+
>filter( /** * @param {number} [pose] * @param {number} [_] */ (pose, _) => true) : number | undefined
35+
>filter : <T>(predicate: (value: T, index: number) => boolean) => T
36+
37+
/**
38+
* @param {number} [pose]
39+
* @param {number} [_]
40+
*/
41+
(pose, _) => true
42+
>(pose, _) => true : (pose?: number | undefined, _?: number | undefined) => true
43+
>pose : number | undefined
44+
>_ : number | undefined
45+
>true : true
46+
47+
);
48+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// repro https://github.com/microsoft/TypeScript/issues/55394
5+
6+
declare function filter<T>(predicate: (value: T, index: number) => boolean): T;
7+
const a = filter((pose?: number) => true);
8+
const b = filter((pose?: number, _?: number) => true);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @strict: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
5+
// @filename: index.js
6+
7+
/**
8+
* @template T
9+
* @param {(value: T, index: number) => boolean} predicate
10+
* @returns {T}
11+
*/
12+
function filter(predicate) {
13+
return /** @type {any} */ (null);
14+
}
15+
16+
const a = filter(
17+
/**
18+
* @param {number} [pose]
19+
*/
20+
(pose) => true
21+
);
22+
23+
const b = filter(
24+
/**
25+
* @param {number} [pose]
26+
* @param {number} [_]
27+
*/
28+
(pose, _) => true
29+
);

0 commit comments

Comments
 (0)