Skip to content

Commit a79d0b1

Browse files
authored
Merge pull request #21292 from Microsoft/fixReverseMappedContravariantInference
Fix reverse mapped contravariant inference
2 parents ac7b87c + 069eac0 commit a79d0b1

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11029,7 +11029,9 @@ namespace ts {
1102911029
const templateType = getTemplateTypeFromMappedType(target);
1103011030
const inference = createInferenceInfo(typeParameter);
1103111031
inferTypes([inference], sourceType, templateType);
11032-
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
11032+
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
11033+
inference.contraCandidates ? getCommonSubtype(inference.contraCandidates) :
11034+
emptyObjectType;
1103311035
}
1103411036

1103511037
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [reverseMappedContravariantInference.ts]
2+
// Repro from #21273
3+
4+
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
5+
conforms({ foo: (v: string) => false })({ foo: "hello" });
6+
7+
8+
//// [reverseMappedContravariantInference.js]
9+
"use strict";
10+
// Repro from #21273
11+
conforms({ foo: function (v) { return false; } })({ foo: "hello" });
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/reverseMappedContravariantInference.ts ===
2+
// Repro from #21273
3+
4+
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
5+
>conforms : Symbol(conforms, Decl(reverseMappedContravariantInference.ts, 0, 0))
6+
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
7+
>source : Symbol(source, Decl(reverseMappedContravariantInference.ts, 2, 29))
8+
>K : Symbol(K, Decl(reverseMappedContravariantInference.ts, 2, 40))
9+
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
10+
>val : Symbol(val, Decl(reverseMappedContravariantInference.ts, 2, 56))
11+
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
12+
>K : Symbol(K, Decl(reverseMappedContravariantInference.ts, 2, 40))
13+
>value : Symbol(value, Decl(reverseMappedContravariantInference.ts, 2, 83))
14+
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
15+
16+
conforms({ foo: (v: string) => false })({ foo: "hello" });
17+
>conforms : Symbol(conforms, Decl(reverseMappedContravariantInference.ts, 0, 0))
18+
>foo : Symbol(foo, Decl(reverseMappedContravariantInference.ts, 3, 10))
19+
>v : Symbol(v, Decl(reverseMappedContravariantInference.ts, 3, 17))
20+
>foo : Symbol(foo, Decl(reverseMappedContravariantInference.ts, 3, 41))
21+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/reverseMappedContravariantInference.ts ===
2+
// Repro from #21273
3+
4+
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
5+
>conforms : <T>(source: { [K in keyof T]: (val: T[K]) => boolean; }) => (value: T) => boolean
6+
>T : T
7+
>source : { [K in keyof T]: (val: T[K]) => boolean; }
8+
>K : K
9+
>T : T
10+
>val : T[K]
11+
>T : T
12+
>K : K
13+
>value : T
14+
>T : T
15+
16+
conforms({ foo: (v: string) => false })({ foo: "hello" });
17+
>conforms({ foo: (v: string) => false })({ foo: "hello" }) : boolean
18+
>conforms({ foo: (v: string) => false }) : (value: { foo: any; }) => boolean
19+
>conforms : <T>(source: { [K in keyof T]: (val: T[K]) => boolean; }) => (value: T) => boolean
20+
>{ foo: (v: string) => false } : { foo: (v: string) => boolean; }
21+
>foo : (v: string) => boolean
22+
>(v: string) => false : (v: string) => boolean
23+
>v : string
24+
>false : false
25+
>{ foo: "hello" } : { foo: string; }
26+
>foo : string
27+
>"hello" : "hello"
28+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @strict: true
2+
3+
// Repro from #21273
4+
5+
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
6+
conforms({ foo: (v: string) => false })({ foo: "hello" });

0 commit comments

Comments
 (0)