Do not covariantly mix in constraints from contravarrying positions (#43439)

* Do not covariantly mix in constraints from contravarrying positions

* Exclude keyof from constraint variance tracking

* Extra test case

* Always subtitute on type parameter types
This commit is contained in:
Wesley Wigham
2021-04-05 11:05:33 -07:00
committed by GitHub
parent 2f36065588
commit f03e59ecc9
5 changed files with 300 additions and 1 deletions

View File

@@ -12854,9 +12854,17 @@ namespace ts {
function getConditionalFlowTypeOfType(type: Type, node: Node) {
let constraints: Type[] | undefined;
let covariant = true;
while (node && !isStatement(node) && node.kind !== SyntaxKind.JSDocComment) {
const parent = node.parent;
if (parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
// only consider variance flipped by parameter locations - `keyof` types would usually be considered variance inverting, but
// often get used in indexed accesses where they behave sortof invariantly, but our checking is lax
if (parent.kind === SyntaxKind.Parameter) {
covariant = !covariant;
}
// Always substitute on type parameters, regardless of variance, since even
// in contravarrying positions, they may be reliant on subtuted constraints to be valid
if ((covariant || type.flags & TypeFlags.TypeParameter) && parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
const constraint = getImpliedConstraint(type, (<ConditionalTypeNode>parent).checkType, (<ConditionalTypeNode>parent).extendsType);
if (constraint) {
constraints = append(constraints, constraint);