|
| 1 | +/* |
| 2 | +
|
| 3 | +Debugging notes: variance measurement for `Parent` is getting set to |
| 4 | +`VarianceFlags.Independent`, implying that its type parameter is never |
| 5 | +witnessed at all. It arrived at this conclusion by checking the assignability |
| 6 | +of `Parent` instantiated with marker types. It first checks assignability in |
| 7 | +both directions with instantiations with super/sub-related marker types, and |
| 8 | +assignability appears to return true in both directions; however, it actually |
| 9 | +is returning `Ternary.Unknown`, due to being unable to answer questions about |
| 10 | +the assignability of the types' `parent` and `child` properties without knowing |
| 11 | +their variances. After (incorrectly) concluding that `Parent` is bivariant on `A`, |
| 12 | +it checks another set of instantiations with markers that are unrelated to each |
| 13 | +other. That too comes back as `Ternary.Unknown` but is interpreted as true, so |
| 14 | +the variance gets updated to `Independent`, since instantiating `Parent` with |
| 15 | +all kinds of different markers with different assignability to each other |
| 16 | +apparently had no effect on the instantiations' assignability to each other. |
| 17 | +
|
| 18 | +I'm not sure if any of those comparisons ever actually looked at `a` and `b`, |
| 19 | +which should provide some non-recursive concrete variance information. I'm also |
| 20 | +not sure if `outofbandVarianceMarkerHandler` should have been called at some point, |
| 21 | +but it was not. |
| 22 | +
|
| 23 | +*/ |
| 24 | + |
| 25 | +interface Parent<A> { |
| 26 | + child: Child<A> | null; |
| 27 | + parent: Parent<A> | null; |
| 28 | +} |
| 29 | + |
| 30 | +interface Child<A, B = unknown> extends Parent<A> { |
| 31 | + readonly a: A; |
| 32 | + // This field isn't necessary to the repro, but the |
| 33 | + // type parameter is, so including it |
| 34 | + readonly b: B; |
| 35 | +} |
| 36 | + |
| 37 | +function fn<A>(inp: Child<A>) { |
| 38 | + // This assignability check defeats the later one |
| 39 | + const a: Child<unknown> = inp; |
| 40 | +} |
| 41 | + |
| 42 | +// Allowed initialization of pu |
| 43 | +const pu: Parent<unknown> = { child: { a: 0, b: 0, child: null, parent: null }, parent: null }; |
| 44 | + |
| 45 | +// Should error |
| 46 | +const notString: Parent<string> = pu; |
0 commit comments