Skip to content

Commit 17e215c

Browse files
committed
Slightly improve test, add comment explaining situation
1 parent 05ac44f commit 17e215c

6 files changed

+66
-6
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11963,11 +11963,20 @@ namespace ts {
1196311963
const mapper = (target as ConditionalType).mapper;
1196411964
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
1196511965
const instantiatedExtends = instantiateType(root.extendsType, mapper);
11966-
const checkConstraint = getSimplifiedType(instantiateType(root.checkType, combineTypeMappers(mapper, getBaseConstraintOrType)));
11967-
inferTypes(context.inferences, checkConstraint, instantiatedExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
11966+
const checkConstraint = getSimplifiedType(instantiateType(root.checkType, mapper));
11967+
// TODO: Use InferencePriority.NoConstraints for type parameters which are being used contravariantly/in a write-only context
11968+
// (Or, ideally, some future InferencePriority.SuperConstraints should we start tracking them!)
11969+
// As-is, this is unsound - it can be made stricter by replacing `instantiateType(root.trueType, combinedMapper)` with
11970+
// `getintersectionType([instantiateType(root.trueType, combinedMapper), instantiateType(root.trueType, mapper)])` which
11971+
// would preserve the type-parametery-ness of the check; but such a limitation makes this branch almost useless, as only
11972+
// conditional types with effectively "independent" inference parameters will end up being assignable via this branch, eg
11973+
// `type InferBecauseWhyNot<T> = T extends (p: infer P1) => any ? T | P1 : never;`
11974+
// contains a union in the `true` branch, and so while we can't confirm assignability to `P1`, we _could_ confirm assignability
11975+
// to `T`.
11976+
inferTypes(context.inferences, checkConstraint, instantiatedExtends, InferencePriority.AlwaysStrict);
1196811977
const combinedMapper = combineTypeMappers(mapper, context);
1196911978
if (isRelatedTo(checkConstraint, instantiateType(root.extendsType, combinedMapper))) {
11970-
if (result = isRelatedTo(source, instantiateType(root.trueType, combinedMapper))) {
11979+
if (result = isRelatedTo(source, instantiateType(root.trueType, combinedMapper), reportErrors)) {
1197111980
errorInfo = saveErrorInfo;
1197211981
return result;
1197311982
}

tests/baselines/reference/genericRestTypes.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type Bind1<T extends (head: any, ...tail: any[]) => any> = (...args: Tail<Parame
2222
>Bind1 : Bind1<T>
2323
>head : any
2424
>tail : any[]
25-
>args : any[]
25+
>args : Tail<Parameters<T>>
2626

2727
type Generic = Bind1<MyFunctionType>; // (bar: string) => boolean
2828
>Generic : Bind1<MyFunctionType>

tests/baselines/reference/thisConditionalInferenceInClassBody.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ class Foo {
1212
}
1313
}
1414

15-
set(new Foo(), 'prop', 'hi'); // <-- typechecks
15+
set(new Foo(), 'prop', 'hi'); // <-- typechecks
16+
17+
type InferBecauseWhyNot<T> = T extends (p: infer P1) => any ? P1 | T : never;
18+
19+
function f<Q extends (arg: any) => any>(x: Q): InferBecauseWhyNot<Q> {
20+
return x;
21+
}
22+
1623

1724
//// [thisConditionalInferenceInClassBody.js]
1825
var Foo = /** @class */ (function () {
@@ -24,3 +31,6 @@ var Foo = /** @class */ (function () {
2431
return Foo;
2532
}());
2633
set(new Foo(), 'prop', 'hi'); // <-- typechecks
34+
function f(x) {
35+
return x;
36+
}

tests/baselines/reference/thisConditionalInferenceInClassBody.symbols

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,25 @@ set(new Foo(), 'prop', 'hi'); // <-- typechecks
5151
>set : Symbol(set, Decl(thisConditionalInferenceInClassBody.ts, 1, 52))
5252
>Foo : Symbol(Foo, Decl(thisConditionalInferenceInClassBody.ts, 3, 94))
5353

54+
type InferBecauseWhyNot<T> = T extends (p: infer P1) => any ? P1 | T : never;
55+
>InferBecauseWhyNot : Symbol(InferBecauseWhyNot, Decl(thisConditionalInferenceInClassBody.ts, 13, 29))
56+
>T : Symbol(T, Decl(thisConditionalInferenceInClassBody.ts, 15, 24))
57+
>T : Symbol(T, Decl(thisConditionalInferenceInClassBody.ts, 15, 24))
58+
>p : Symbol(p, Decl(thisConditionalInferenceInClassBody.ts, 15, 40))
59+
>P1 : Symbol(P1, Decl(thisConditionalInferenceInClassBody.ts, 15, 48))
60+
>P1 : Symbol(P1, Decl(thisConditionalInferenceInClassBody.ts, 15, 48))
61+
>T : Symbol(T, Decl(thisConditionalInferenceInClassBody.ts, 15, 24))
62+
63+
function f<Q extends (arg: any) => any>(x: Q): InferBecauseWhyNot<Q> {
64+
>f : Symbol(f, Decl(thisConditionalInferenceInClassBody.ts, 15, 77))
65+
>Q : Symbol(Q, Decl(thisConditionalInferenceInClassBody.ts, 17, 11))
66+
>arg : Symbol(arg, Decl(thisConditionalInferenceInClassBody.ts, 17, 22))
67+
>x : Symbol(x, Decl(thisConditionalInferenceInClassBody.ts, 17, 40))
68+
>Q : Symbol(Q, Decl(thisConditionalInferenceInClassBody.ts, 17, 11))
69+
>InferBecauseWhyNot : Symbol(InferBecauseWhyNot, Decl(thisConditionalInferenceInClassBody.ts, 13, 29))
70+
>Q : Symbol(Q, Decl(thisConditionalInferenceInClassBody.ts, 17, 11))
71+
72+
return x;
73+
>x : Symbol(x, Decl(thisConditionalInferenceInClassBody.ts, 17, 40))
74+
}
75+

tests/baselines/reference/thisConditionalInferenceInClassBody.types

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,16 @@ set(new Foo(), 'prop', 'hi'); // <-- typechecks
3838
>'prop' : "prop"
3939
>'hi' : "hi"
4040

41+
type InferBecauseWhyNot<T> = T extends (p: infer P1) => any ? P1 | T : never;
42+
>InferBecauseWhyNot : InferBecauseWhyNot<T>
43+
>p : P1
44+
45+
function f<Q extends (arg: any) => any>(x: Q): InferBecauseWhyNot<Q> {
46+
>f : <Q extends (arg: any) => any>(x: Q) => InferBecauseWhyNot<Q>
47+
>arg : any
48+
>x : Q
49+
50+
return x;
51+
>x : Q
52+
}
53+

tests/cases/compiler/thisConditionalInferenceInClassBody.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ class Foo {
1111
}
1212
}
1313

14-
set(new Foo(), 'prop', 'hi'); // <-- typechecks
14+
set(new Foo(), 'prop', 'hi'); // <-- typechecks
15+
16+
type InferBecauseWhyNot<T> = T extends (p: infer P1) => any ? P1 | T : never;
17+
18+
function f<Q extends (arg: any) => any>(x: Q): InferBecauseWhyNot<Q> {
19+
return x;
20+
}

0 commit comments

Comments
 (0)