From 662230820603c7e5d495a0869e11ea18392ff76e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:53:03 -0800 Subject: [PATCH] Add followup test to #52123 test (#52178) --- .../coAndContraVariantInferences2.js | 19 + .../coAndContraVariantInferences2.symbols | 339 ++++++++++-------- .../coAndContraVariantInferences2.types | 25 ++ .../compiler/coAndContraVariantInferences2.ts | 11 + 4 files changed, 242 insertions(+), 152 deletions(-) diff --git a/tests/baselines/reference/coAndContraVariantInferences2.js b/tests/baselines/reference/coAndContraVariantInferences2.js index f2bb2a4374e23..88c94f80e37b6 100644 --- a/tests/baselines/reference/coAndContraVariantInferences2.js +++ b/tests/baselines/reference/coAndContraVariantInferences2.js @@ -23,6 +23,17 @@ function f2(b: B, c: C) { consume(c, c, useA); // consume } +declare function every(array: readonly T[], f: (x: T) => x is U): array is readonly U[]; + +function f3(arr: readonly B[] | readonly C[]) { + if (every(arr, isC)) { + arr; // readonly C[] + } + else { + arr; // readonly B[] + } +} + // Repro from #52111 enum SyntaxKind { @@ -120,6 +131,14 @@ function f2(b, c) { consume(b, b, useA); // consume consume(c, c, useA); // consume } +function f3(arr) { + if (every(arr, isC)) { + arr; // readonly C[] + } + else { + arr; // readonly B[] + } +} // Repro from #52111 var SyntaxKind; (function (SyntaxKind) { diff --git a/tests/baselines/reference/coAndContraVariantInferences2.symbols b/tests/baselines/reference/coAndContraVariantInferences2.symbols index b91904fca99ba..dffee728c2fbb 100644 --- a/tests/baselines/reference/coAndContraVariantInferences2.symbols +++ b/tests/baselines/reference/coAndContraVariantInferences2.symbols @@ -104,264 +104,299 @@ function f2(b: B, c: C) { >useA : Symbol(useA, Decl(coAndContraVariantInferences2.ts, 11, 1)) } +declare function every(array: readonly T[], f: (x: T) => x is U): array is readonly U[]; +>every : Symbol(every, Decl(coAndContraVariantInferences2.ts, 22, 1)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 24, 23)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 24, 25)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 24, 23)) +>array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 24, 39)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 24, 23)) +>f : Symbol(f, Decl(coAndContraVariantInferences2.ts, 24, 59)) +>x : Symbol(x, Decl(coAndContraVariantInferences2.ts, 24, 64)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 24, 23)) +>x : Symbol(x, Decl(coAndContraVariantInferences2.ts, 24, 64)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 24, 25)) +>array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 24, 39)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 24, 25)) + +function f3(arr: readonly B[] | readonly C[]) { +>f3 : Symbol(f3, Decl(coAndContraVariantInferences2.ts, 24, 104)) +>arr : Symbol(arr, Decl(coAndContraVariantInferences2.ts, 26, 12)) +>B : Symbol(B, Decl(coAndContraVariantInferences2.ts, 0, 25)) +>C : Symbol(C, Decl(coAndContraVariantInferences2.ts, 1, 35)) + + if (every(arr, isC)) { +>every : Symbol(every, Decl(coAndContraVariantInferences2.ts, 22, 1)) +>arr : Symbol(arr, Decl(coAndContraVariantInferences2.ts, 26, 12)) +>isC : Symbol(isC, Decl(coAndContraVariantInferences2.ts, 4, 71)) + + arr; // readonly C[] +>arr : Symbol(arr, Decl(coAndContraVariantInferences2.ts, 26, 12)) + } + else { + arr; // readonly B[] +>arr : Symbol(arr, Decl(coAndContraVariantInferences2.ts, 26, 12)) + } +} + // Repro from #52111 enum SyntaxKind { ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) Block, ->Block : Symbol(SyntaxKind.Block, Decl(coAndContraVariantInferences2.ts, 26, 17)) +>Block : Symbol(SyntaxKind.Block, Decl(coAndContraVariantInferences2.ts, 37, 17)) Identifier, ->Identifier : Symbol(SyntaxKind.Identifier, Decl(coAndContraVariantInferences2.ts, 27, 10)) +>Identifier : Symbol(SyntaxKind.Identifier, Decl(coAndContraVariantInferences2.ts, 38, 10)) CaseClause, ->CaseClause : Symbol(SyntaxKind.CaseClause, Decl(coAndContraVariantInferences2.ts, 28, 15)) +>CaseClause : Symbol(SyntaxKind.CaseClause, Decl(coAndContraVariantInferences2.ts, 39, 15)) FunctionExpression, ->FunctionExpression : Symbol(SyntaxKind.FunctionExpression, Decl(coAndContraVariantInferences2.ts, 29, 15)) +>FunctionExpression : Symbol(SyntaxKind.FunctionExpression, Decl(coAndContraVariantInferences2.ts, 40, 15)) FunctionDeclaration, ->FunctionDeclaration : Symbol(SyntaxKind.FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 30, 23)) +>FunctionDeclaration : Symbol(SyntaxKind.FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 41, 23)) } interface Node { kind: SyntaxKind; } ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->kind : Symbol(Node.kind, Decl(coAndContraVariantInferences2.ts, 34, 16)) ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>kind : Symbol(Node.kind, Decl(coAndContraVariantInferences2.ts, 45, 16)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) interface Expression extends Node { _expressionBrand: any; } ->Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 34, 36)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->_expressionBrand : Symbol(Expression._expressionBrand, Decl(coAndContraVariantInferences2.ts, 35, 35)) +>Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 45, 36)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>_expressionBrand : Symbol(Expression._expressionBrand, Decl(coAndContraVariantInferences2.ts, 46, 35)) interface Declaration extends Node { _declarationBrand: any; } ->Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 35, 60)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->_declarationBrand : Symbol(Declaration._declarationBrand, Decl(coAndContraVariantInferences2.ts, 36, 36)) +>Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 46, 60)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>_declarationBrand : Symbol(Declaration._declarationBrand, Decl(coAndContraVariantInferences2.ts, 47, 36)) interface Block extends Node { kind: SyntaxKind.Block; } ->Block : Symbol(Block, Decl(coAndContraVariantInferences2.ts, 36, 62)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->kind : Symbol(Block.kind, Decl(coAndContraVariantInferences2.ts, 37, 30)) ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) ->Block : Symbol(SyntaxKind.Block, Decl(coAndContraVariantInferences2.ts, 26, 17)) +>Block : Symbol(Block, Decl(coAndContraVariantInferences2.ts, 47, 62)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>kind : Symbol(Block.kind, Decl(coAndContraVariantInferences2.ts, 48, 30)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) +>Block : Symbol(SyntaxKind.Block, Decl(coAndContraVariantInferences2.ts, 37, 17)) interface Identifier extends Expression, Declaration { kind: SyntaxKind.Identifier; } ->Identifier : Symbol(Identifier, Decl(coAndContraVariantInferences2.ts, 37, 56)) ->Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 34, 36)) ->Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 35, 60)) ->kind : Symbol(Identifier.kind, Decl(coAndContraVariantInferences2.ts, 38, 54)) ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) ->Identifier : Symbol(SyntaxKind.Identifier, Decl(coAndContraVariantInferences2.ts, 27, 10)) +>Identifier : Symbol(Identifier, Decl(coAndContraVariantInferences2.ts, 48, 56)) +>Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 45, 36)) +>Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 46, 60)) +>kind : Symbol(Identifier.kind, Decl(coAndContraVariantInferences2.ts, 49, 54)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) +>Identifier : Symbol(SyntaxKind.Identifier, Decl(coAndContraVariantInferences2.ts, 38, 10)) interface CaseClause extends Node { kind: SyntaxKind.CaseClause; } ->CaseClause : Symbol(CaseClause, Decl(coAndContraVariantInferences2.ts, 38, 85)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->kind : Symbol(CaseClause.kind, Decl(coAndContraVariantInferences2.ts, 39, 35)) ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) ->CaseClause : Symbol(SyntaxKind.CaseClause, Decl(coAndContraVariantInferences2.ts, 28, 15)) +>CaseClause : Symbol(CaseClause, Decl(coAndContraVariantInferences2.ts, 49, 85)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>kind : Symbol(CaseClause.kind, Decl(coAndContraVariantInferences2.ts, 50, 35)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) +>CaseClause : Symbol(SyntaxKind.CaseClause, Decl(coAndContraVariantInferences2.ts, 39, 15)) interface FunctionDeclaration extends Declaration { kind: SyntaxKind.FunctionDeclaration; } ->FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 39, 66)) ->Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 35, 60)) ->kind : Symbol(FunctionDeclaration.kind, Decl(coAndContraVariantInferences2.ts, 40, 51)) ->SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 22, 1)) ->FunctionDeclaration : Symbol(SyntaxKind.FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 30, 23)) +>FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 50, 66)) +>Declaration : Symbol(Declaration, Decl(coAndContraVariantInferences2.ts, 46, 60)) +>kind : Symbol(FunctionDeclaration.kind, Decl(coAndContraVariantInferences2.ts, 51, 51)) +>SyntaxKind : Symbol(SyntaxKind, Decl(coAndContraVariantInferences2.ts, 33, 1)) +>FunctionDeclaration : Symbol(SyntaxKind.FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 41, 23)) type HasLocals = Block | FunctionDeclaration; ->HasLocals : Symbol(HasLocals, Decl(coAndContraVariantInferences2.ts, 40, 91)) ->Block : Symbol(Block, Decl(coAndContraVariantInferences2.ts, 36, 62)) ->FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 39, 66)) +>HasLocals : Symbol(HasLocals, Decl(coAndContraVariantInferences2.ts, 51, 91)) +>Block : Symbol(Block, Decl(coAndContraVariantInferences2.ts, 47, 62)) +>FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 50, 66)) declare function canHaveLocals(node: Node): node is HasLocals; ->canHaveLocals : Symbol(canHaveLocals, Decl(coAndContraVariantInferences2.ts, 42, 45)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 43, 31)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 43, 31)) ->HasLocals : Symbol(HasLocals, Decl(coAndContraVariantInferences2.ts, 40, 91)) +>canHaveLocals : Symbol(canHaveLocals, Decl(coAndContraVariantInferences2.ts, 53, 45)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 54, 31)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 54, 31)) +>HasLocals : Symbol(HasLocals, Decl(coAndContraVariantInferences2.ts, 51, 91)) declare function assertNode(node: T | undefined, test: (node: T) => node is U): asserts node is U; ->assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 43, 62), Decl(coAndContraVariantInferences2.ts, 45, 127)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 45, 28)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 45, 43)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 45, 28)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 45, 57)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 45, 28)) ->test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 45, 77)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 45, 85)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 45, 28)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 45, 85)) ->U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 45, 43)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 45, 57)) ->U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 45, 43)) +>assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 54, 62), Decl(coAndContraVariantInferences2.ts, 56, 127)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 56, 28)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 56, 43)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 56, 28)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 56, 57)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 56, 28)) +>test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 56, 77)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 56, 85)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 56, 28)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 56, 85)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 56, 43)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 56, 57)) +>U : Symbol(U, Decl(coAndContraVariantInferences2.ts, 56, 43)) declare function assertNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined): void; ->assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 43, 62), Decl(coAndContraVariantInferences2.ts, 45, 127)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 46, 28)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 46, 51)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 46, 60)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) +>assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 54, 62), Decl(coAndContraVariantInferences2.ts, 56, 127)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 57, 28)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 57, 51)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 57, 60)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) function foo(node: FunctionDeclaration | CaseClause) { ->foo : Symbol(foo, Decl(coAndContraVariantInferences2.ts, 46, 103)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 48, 13)) ->FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 39, 66)) ->CaseClause : Symbol(CaseClause, Decl(coAndContraVariantInferences2.ts, 38, 85)) +>foo : Symbol(foo, Decl(coAndContraVariantInferences2.ts, 57, 103)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 59, 13)) +>FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 50, 66)) +>CaseClause : Symbol(CaseClause, Decl(coAndContraVariantInferences2.ts, 49, 85)) assertNode(node, canHaveLocals); // assertNode ->assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 43, 62), Decl(coAndContraVariantInferences2.ts, 45, 127)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 48, 13)) ->canHaveLocals : Symbol(canHaveLocals, Decl(coAndContraVariantInferences2.ts, 42, 45)) +>assertNode : Symbol(assertNode, Decl(coAndContraVariantInferences2.ts, 54, 62), Decl(coAndContraVariantInferences2.ts, 56, 127)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 59, 13)) +>canHaveLocals : Symbol(canHaveLocals, Decl(coAndContraVariantInferences2.ts, 53, 45)) node; // FunctionDeclaration ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 48, 13)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 59, 13)) } declare function isExpression(node: Node): node is Expression; ->isExpression : Symbol(isExpression, Decl(coAndContraVariantInferences2.ts, 51, 1)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 53, 30)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 53, 30)) ->Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 34, 36)) +>isExpression : Symbol(isExpression, Decl(coAndContraVariantInferences2.ts, 62, 1)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 64, 30)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 64, 30)) +>Expression : Symbol(Expression, Decl(coAndContraVariantInferences2.ts, 45, 36)) declare function tryCast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut; ->tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 53, 62)) ->TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 55, 25)) ->TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 55, 42)) ->TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 55, 42)) ->value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 55, 54)) ->TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 55, 42)) ->test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 55, 77)) ->value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 55, 85)) ->TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 55, 42)) ->value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 55, 85)) ->TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 55, 25)) ->TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 55, 25)) +>tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 64, 62)) +>TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 66, 25)) +>TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 66, 42)) +>TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 66, 42)) +>value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 66, 54)) +>TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 66, 42)) +>test : Symbol(test, Decl(coAndContraVariantInferences2.ts, 66, 77)) +>value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 66, 85)) +>TIn : Symbol(TIn, Decl(coAndContraVariantInferences2.ts, 66, 42)) +>value : Symbol(value, Decl(coAndContraVariantInferences2.ts, 66, 85)) +>TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 66, 25)) +>TOut : Symbol(TOut, Decl(coAndContraVariantInferences2.ts, 66, 25)) function bar(node: Identifier | FunctionDeclaration) { ->bar : Symbol(bar, Decl(coAndContraVariantInferences2.ts, 55, 121)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 57, 13)) ->Identifier : Symbol(Identifier, Decl(coAndContraVariantInferences2.ts, 37, 56)) ->FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 39, 66)) +>bar : Symbol(bar, Decl(coAndContraVariantInferences2.ts, 66, 121)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 68, 13)) +>Identifier : Symbol(Identifier, Decl(coAndContraVariantInferences2.ts, 48, 56)) +>FunctionDeclaration : Symbol(FunctionDeclaration, Decl(coAndContraVariantInferences2.ts, 50, 66)) const a = tryCast(node, isExpression); // tryCast ->a : Symbol(a, Decl(coAndContraVariantInferences2.ts, 58, 9)) ->tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 53, 62)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 57, 13)) ->isExpression : Symbol(isExpression, Decl(coAndContraVariantInferences2.ts, 51, 1)) +>a : Symbol(a, Decl(coAndContraVariantInferences2.ts, 69, 9)) +>tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 64, 62)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 68, 13)) +>isExpression : Symbol(isExpression, Decl(coAndContraVariantInferences2.ts, 62, 1)) } // Repro from #49924 const enum SyntaxKind1 { ->SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 59, 1)) +>SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 70, 1)) ClassExpression, ->ClassExpression : Symbol(SyntaxKind1.ClassExpression, Decl(coAndContraVariantInferences2.ts, 63, 24)) +>ClassExpression : Symbol(SyntaxKind1.ClassExpression, Decl(coAndContraVariantInferences2.ts, 74, 24)) ClassStatement, ->ClassStatement : Symbol(SyntaxKind1.ClassStatement, Decl(coAndContraVariantInferences2.ts, 64, 20)) +>ClassStatement : Symbol(SyntaxKind1.ClassStatement, Decl(coAndContraVariantInferences2.ts, 75, 20)) } interface Node1 { ->Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 66, 1)) +>Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 77, 1)) kind: SyntaxKind1; ->kind : Symbol(Node1.kind, Decl(coAndContraVariantInferences2.ts, 68, 17)) ->SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 59, 1)) +>kind : Symbol(Node1.kind, Decl(coAndContraVariantInferences2.ts, 79, 17)) +>SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 70, 1)) } interface Statement1 extends Node1 { ->Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 70, 1)) ->Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 66, 1)) +>Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 81, 1)) +>Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 77, 1)) _statementBrand: any; ->_statementBrand : Symbol(Statement1._statementBrand, Decl(coAndContraVariantInferences2.ts, 72, 36)) +>_statementBrand : Symbol(Statement1._statementBrand, Decl(coAndContraVariantInferences2.ts, 83, 36)) } interface ClassExpression1 extends Node1 { ->ClassExpression1 : Symbol(ClassExpression1, Decl(coAndContraVariantInferences2.ts, 74, 1)) ->Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 66, 1)) +>ClassExpression1 : Symbol(ClassExpression1, Decl(coAndContraVariantInferences2.ts, 85, 1)) +>Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 77, 1)) kind: SyntaxKind1.ClassExpression; ->kind : Symbol(ClassExpression1.kind, Decl(coAndContraVariantInferences2.ts, 76, 42)) ->SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 59, 1)) ->ClassExpression : Symbol(SyntaxKind1.ClassExpression, Decl(coAndContraVariantInferences2.ts, 63, 24)) +>kind : Symbol(ClassExpression1.kind, Decl(coAndContraVariantInferences2.ts, 87, 42)) +>SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 70, 1)) +>ClassExpression : Symbol(SyntaxKind1.ClassExpression, Decl(coAndContraVariantInferences2.ts, 74, 24)) } interface ClassStatement1 extends Statement1 { ->ClassStatement1 : Symbol(ClassStatement1, Decl(coAndContraVariantInferences2.ts, 78, 1)) ->Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 70, 1)) +>ClassStatement1 : Symbol(ClassStatement1, Decl(coAndContraVariantInferences2.ts, 89, 1)) +>Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 81, 1)) kind: SyntaxKind1.ClassStatement; ->kind : Symbol(ClassStatement1.kind, Decl(coAndContraVariantInferences2.ts, 80, 46)) ->SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 59, 1)) ->ClassStatement : Symbol(SyntaxKind1.ClassStatement, Decl(coAndContraVariantInferences2.ts, 64, 20)) +>kind : Symbol(ClassStatement1.kind, Decl(coAndContraVariantInferences2.ts, 91, 46)) +>SyntaxKind1 : Symbol(SyntaxKind1, Decl(coAndContraVariantInferences2.ts, 70, 1)) +>ClassStatement : Symbol(SyntaxKind1.ClassStatement, Decl(coAndContraVariantInferences2.ts, 75, 20)) } type ClassLike1 = ClassExpression1 | ClassStatement1; ->ClassLike1 : Symbol(ClassLike1, Decl(coAndContraVariantInferences2.ts, 82, 1)) ->ClassExpression1 : Symbol(ClassExpression1, Decl(coAndContraVariantInferences2.ts, 74, 1)) ->ClassStatement1 : Symbol(ClassStatement1, Decl(coAndContraVariantInferences2.ts, 78, 1)) +>ClassLike1 : Symbol(ClassLike1, Decl(coAndContraVariantInferences2.ts, 93, 1)) +>ClassExpression1 : Symbol(ClassExpression1, Decl(coAndContraVariantInferences2.ts, 85, 1)) +>ClassStatement1 : Symbol(ClassStatement1, Decl(coAndContraVariantInferences2.ts, 89, 1)) declare function isClassLike(node: Node1): node is ClassLike1; ->isClassLike : Symbol(isClassLike, Decl(coAndContraVariantInferences2.ts, 84, 53)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 86, 29)) ->Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 66, 1)) ->node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 86, 29)) ->ClassLike1 : Symbol(ClassLike1, Decl(coAndContraVariantInferences2.ts, 82, 1)) +>isClassLike : Symbol(isClassLike, Decl(coAndContraVariantInferences2.ts, 95, 53)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 97, 29)) +>Node1 : Symbol(Node1, Decl(coAndContraVariantInferences2.ts, 77, 1)) +>node : Symbol(node, Decl(coAndContraVariantInferences2.ts, 97, 29)) +>ClassLike1 : Symbol(ClassLike1, Decl(coAndContraVariantInferences2.ts, 93, 1)) declare const statement: Statement1 | undefined; ->statement : Symbol(statement, Decl(coAndContraVariantInferences2.ts, 88, 13)) ->Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 70, 1)) +>statement : Symbol(statement, Decl(coAndContraVariantInferences2.ts, 99, 13)) +>Statement1 : Symbol(Statement1, Decl(coAndContraVariantInferences2.ts, 81, 1)) const maybeClassStatement = tryCast(statement, isClassLike); // ClassLike1 ->maybeClassStatement : Symbol(maybeClassStatement, Decl(coAndContraVariantInferences2.ts, 90, 5)) ->tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 53, 62)) ->statement : Symbol(statement, Decl(coAndContraVariantInferences2.ts, 88, 13)) ->isClassLike : Symbol(isClassLike, Decl(coAndContraVariantInferences2.ts, 84, 53)) +>maybeClassStatement : Symbol(maybeClassStatement, Decl(coAndContraVariantInferences2.ts, 101, 5)) +>tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 64, 62)) +>statement : Symbol(statement, Decl(coAndContraVariantInferences2.ts, 99, 13)) +>isClassLike : Symbol(isClassLike, Decl(coAndContraVariantInferences2.ts, 95, 53)) // Repro from #49924 interface TypeNode extends Node { ->TypeNode : Symbol(TypeNode, Decl(coAndContraVariantInferences2.ts, 90, 60)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) +>TypeNode : Symbol(TypeNode, Decl(coAndContraVariantInferences2.ts, 101, 60)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) typeInfo: string; ->typeInfo : Symbol(TypeNode.typeInfo, Decl(coAndContraVariantInferences2.ts, 94, 33)) +>typeInfo : Symbol(TypeNode.typeInfo, Decl(coAndContraVariantInferences2.ts, 105, 33)) } interface NodeArray extends Array { ->NodeArray : Symbol(NodeArray, Decl(coAndContraVariantInferences2.ts, 96, 1)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 98, 20)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) +>NodeArray : Symbol(NodeArray, Decl(coAndContraVariantInferences2.ts, 107, 1)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 109, 20)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 98, 20)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 109, 20)) someProp: string; ->someProp : Symbol(NodeArray.someProp, Decl(coAndContraVariantInferences2.ts, 98, 54)) +>someProp : Symbol(NodeArray.someProp, Decl(coAndContraVariantInferences2.ts, 109, 54)) } declare function isNodeArray(array: readonly T[]): array is NodeArray; ->isNodeArray : Symbol(isNodeArray, Decl(coAndContraVariantInferences2.ts, 100, 1)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 102, 29)) ->Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 32, 1)) ->array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 102, 45)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 102, 29)) ->array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 102, 45)) ->NodeArray : Symbol(NodeArray, Decl(coAndContraVariantInferences2.ts, 96, 1)) ->T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 102, 29)) +>isNodeArray : Symbol(isNodeArray, Decl(coAndContraVariantInferences2.ts, 111, 1)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 113, 29)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(coAndContraVariantInferences2.ts, 43, 1)) +>array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 113, 45)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 113, 29)) +>array : Symbol(array, Decl(coAndContraVariantInferences2.ts, 113, 45)) +>NodeArray : Symbol(NodeArray, Decl(coAndContraVariantInferences2.ts, 107, 1)) +>T : Symbol(T, Decl(coAndContraVariantInferences2.ts, 113, 29)) declare const types: readonly TypeNode[]; ->types : Symbol(types, Decl(coAndContraVariantInferences2.ts, 104, 13)) ->TypeNode : Symbol(TypeNode, Decl(coAndContraVariantInferences2.ts, 90, 60)) +>types : Symbol(types, Decl(coAndContraVariantInferences2.ts, 115, 13)) +>TypeNode : Symbol(TypeNode, Decl(coAndContraVariantInferences2.ts, 101, 60)) const x = tryCast(types, isNodeArray); // NodeAray ->x : Symbol(x, Decl(coAndContraVariantInferences2.ts, 106, 5)) ->tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 53, 62)) ->types : Symbol(types, Decl(coAndContraVariantInferences2.ts, 104, 13)) ->isNodeArray : Symbol(isNodeArray, Decl(coAndContraVariantInferences2.ts, 100, 1)) +>x : Symbol(x, Decl(coAndContraVariantInferences2.ts, 117, 5)) +>tryCast : Symbol(tryCast, Decl(coAndContraVariantInferences2.ts, 64, 62)) +>types : Symbol(types, Decl(coAndContraVariantInferences2.ts, 115, 13)) +>isNodeArray : Symbol(isNodeArray, Decl(coAndContraVariantInferences2.ts, 111, 1)) diff --git a/tests/baselines/reference/coAndContraVariantInferences2.types b/tests/baselines/reference/coAndContraVariantInferences2.types index 1e332d285b412..bcf99cca88d0d 100644 --- a/tests/baselines/reference/coAndContraVariantInferences2.types +++ b/tests/baselines/reference/coAndContraVariantInferences2.types @@ -83,6 +83,31 @@ function f2(b: B, c: C) { >useA : (a: A) => void } +declare function every(array: readonly T[], f: (x: T) => x is U): array is readonly U[]; +>every : (array: readonly T[], f: (x: T) => x is U) => array is readonly U[] +>array : readonly T[] +>f : (x: T) => x is U +>x : T + +function f3(arr: readonly B[] | readonly C[]) { +>f3 : (arr: readonly B[] | readonly C[]) => void +>arr : readonly B[] | readonly C[] + + if (every(arr, isC)) { +>every(arr, isC) : boolean +>every : (array: readonly T[], f: (x: T) => x is U) => array is readonly U[] +>arr : readonly B[] | readonly C[] +>isC : (x: A) => x is C + + arr; // readonly C[] +>arr : readonly C[] + } + else { + arr; // readonly B[] +>arr : readonly B[] + } +} + // Repro from #52111 enum SyntaxKind { diff --git a/tests/cases/compiler/coAndContraVariantInferences2.ts b/tests/cases/compiler/coAndContraVariantInferences2.ts index d7d486442cbc1..3292a06440022 100644 --- a/tests/cases/compiler/coAndContraVariantInferences2.ts +++ b/tests/cases/compiler/coAndContraVariantInferences2.ts @@ -24,6 +24,17 @@ function f2(b: B, c: C) { consume(c, c, useA); // consume } +declare function every(array: readonly T[], f: (x: T) => x is U): array is readonly U[]; + +function f3(arr: readonly B[] | readonly C[]) { + if (every(arr, isC)) { + arr; // readonly C[] + } + else { + arr; // readonly B[] + } +} + // Repro from #52111 enum SyntaxKind {