-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🤖 Pick PR #53351 (Fix subtype reduction involving typ...) into releas…
…e-5.0 (#53422) Co-authored-by: Anders Hejlsberg <[email protected]>
- Loading branch information
1 parent
b345c3a
commit 7e093f0
Showing
4 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
tests/baselines/reference/subtypeReductionUnionConstraints.symbols
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
=== tests/cases/compiler/subtypeReductionUnionConstraints.ts === | ||
// Repro from #53311 | ||
|
||
type FooNode = { | ||
>FooNode : Symbol(FooNode, Decl(subtypeReductionUnionConstraints.ts, 0, 0)) | ||
|
||
kind: 'foo'; | ||
>kind : Symbol(kind, Decl(subtypeReductionUnionConstraints.ts, 2, 16)) | ||
|
||
children: Node[]; | ||
>children : Symbol(children, Decl(subtypeReductionUnionConstraints.ts, 3, 16)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
|
||
}; | ||
|
||
type BarNode = { | ||
>BarNode : Symbol(BarNode, Decl(subtypeReductionUnionConstraints.ts, 5, 2)) | ||
|
||
kind: 'bar'; | ||
>kind : Symbol(kind, Decl(subtypeReductionUnionConstraints.ts, 7, 16)) | ||
} | ||
|
||
type Node = FooNode | BarNode; | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>FooNode : Symbol(FooNode, Decl(subtypeReductionUnionConstraints.ts, 0, 0)) | ||
>BarNode : Symbol(BarNode, Decl(subtypeReductionUnionConstraints.ts, 5, 2)) | ||
|
||
type Document = { | ||
>Document : Symbol(Document, Decl(subtypeReductionUnionConstraints.ts, 11, 30)) | ||
|
||
kind: 'document'; | ||
>kind : Symbol(kind, Decl(subtypeReductionUnionConstraints.ts, 13, 17)) | ||
|
||
children: Node[]; | ||
>children : Symbol(children, Decl(subtypeReductionUnionConstraints.ts, 14, 21)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
|
||
}; | ||
|
||
declare function isNode(node: unknown): node is Node; | ||
>isNode : Symbol(isNode, Decl(subtypeReductionUnionConstraints.ts, 16, 2)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 18, 24)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 18, 24)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
|
||
declare function isBar(node: Node): node is BarNode; | ||
>isBar : Symbol(isBar, Decl(subtypeReductionUnionConstraints.ts, 18, 53)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 19, 23)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 19, 23)) | ||
>BarNode : Symbol(BarNode, Decl(subtypeReductionUnionConstraints.ts, 5, 2)) | ||
|
||
export function visitNodes<T extends Node>(node: Document | Node, predicate: (testNode: Node) => testNode is T): void { | ||
>visitNodes : Symbol(visitNodes, Decl(subtypeReductionUnionConstraints.ts, 19, 52)) | ||
>T : Symbol(T, Decl(subtypeReductionUnionConstraints.ts, 21, 27)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
>Document : Symbol(Document, Decl(subtypeReductionUnionConstraints.ts, 11, 30)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>predicate : Symbol(predicate, Decl(subtypeReductionUnionConstraints.ts, 21, 65)) | ||
>testNode : Symbol(testNode, Decl(subtypeReductionUnionConstraints.ts, 21, 78)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>testNode : Symbol(testNode, Decl(subtypeReductionUnionConstraints.ts, 21, 78)) | ||
>T : Symbol(T, Decl(subtypeReductionUnionConstraints.ts, 21, 27)) | ||
|
||
isNode(node) && predicate(node); | ||
>isNode : Symbol(isNode, Decl(subtypeReductionUnionConstraints.ts, 16, 2)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
>predicate : Symbol(predicate, Decl(subtypeReductionUnionConstraints.ts, 21, 65)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
|
||
if (!isNode(node) || !isBar(node)) { | ||
>isNode : Symbol(isNode, Decl(subtypeReductionUnionConstraints.ts, 16, 2)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
>isBar : Symbol(isBar, Decl(subtypeReductionUnionConstraints.ts, 18, 53)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
|
||
const nodes: Node[] = node.children; | ||
>nodes : Symbol(nodes, Decl(subtypeReductionUnionConstraints.ts, 24, 13)) | ||
>Node : Symbol(Node, Decl(subtypeReductionUnionConstraints.ts, 9, 1)) | ||
>node.children : Symbol(children, Decl(subtypeReductionUnionConstraints.ts, 3, 16), Decl(subtypeReductionUnionConstraints.ts, 14, 21)) | ||
>node : Symbol(node, Decl(subtypeReductionUnionConstraints.ts, 21, 43)) | ||
>children : Symbol(children, Decl(subtypeReductionUnionConstraints.ts, 3, 16), Decl(subtypeReductionUnionConstraints.ts, 14, 21)) | ||
} | ||
} | ||
|
||
// Repro from #53311 | ||
|
||
type A = { a: string }; | ||
>A : Symbol(A, Decl(subtypeReductionUnionConstraints.ts, 26, 1)) | ||
>a : Symbol(a, Decl(subtypeReductionUnionConstraints.ts, 30, 10)) | ||
|
||
type B = { b: string }; | ||
>B : Symbol(B, Decl(subtypeReductionUnionConstraints.ts, 30, 23)) | ||
>b : Symbol(b, Decl(subtypeReductionUnionConstraints.ts, 31, 10)) | ||
|
||
function f1<T extends A | B>(t: T, x: A | B) { | ||
>f1 : Symbol(f1, Decl(subtypeReductionUnionConstraints.ts, 31, 23)) | ||
>T : Symbol(T, Decl(subtypeReductionUnionConstraints.ts, 33, 12)) | ||
>A : Symbol(A, Decl(subtypeReductionUnionConstraints.ts, 26, 1)) | ||
>B : Symbol(B, Decl(subtypeReductionUnionConstraints.ts, 30, 23)) | ||
>t : Symbol(t, Decl(subtypeReductionUnionConstraints.ts, 33, 29)) | ||
>T : Symbol(T, Decl(subtypeReductionUnionConstraints.ts, 33, 12)) | ||
>x : Symbol(x, Decl(subtypeReductionUnionConstraints.ts, 33, 34)) | ||
>A : Symbol(A, Decl(subtypeReductionUnionConstraints.ts, 26, 1)) | ||
>B : Symbol(B, Decl(subtypeReductionUnionConstraints.ts, 30, 23)) | ||
|
||
const a = [t, x]; // (A | B)[] by subtype reduction | ||
>a : Symbol(a, Decl(subtypeReductionUnionConstraints.ts, 34, 9)) | ||
>t : Symbol(t, Decl(subtypeReductionUnionConstraints.ts, 33, 29)) | ||
>x : Symbol(x, Decl(subtypeReductionUnionConstraints.ts, 33, 34)) | ||
} | ||
|
99 changes: 99 additions & 0 deletions
99
tests/baselines/reference/subtypeReductionUnionConstraints.types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
=== tests/cases/compiler/subtypeReductionUnionConstraints.ts === | ||
// Repro from #53311 | ||
|
||
type FooNode = { | ||
>FooNode : { kind: 'foo'; children: Node[]; } | ||
|
||
kind: 'foo'; | ||
>kind : "foo" | ||
|
||
children: Node[]; | ||
>children : Node[] | ||
|
||
}; | ||
|
||
type BarNode = { | ||
>BarNode : { kind: 'bar'; } | ||
|
||
kind: 'bar'; | ||
>kind : "bar" | ||
} | ||
|
||
type Node = FooNode | BarNode; | ||
>Node : FooNode | BarNode | ||
|
||
type Document = { | ||
>Document : { kind: 'document'; children: Node[]; } | ||
|
||
kind: 'document'; | ||
>kind : "document" | ||
|
||
children: Node[]; | ||
>children : Node[] | ||
|
||
}; | ||
|
||
declare function isNode(node: unknown): node is Node; | ||
>isNode : (node: unknown) => node is Node | ||
>node : unknown | ||
|
||
declare function isBar(node: Node): node is BarNode; | ||
>isBar : (node: Node) => node is BarNode | ||
>node : Node | ||
|
||
export function visitNodes<T extends Node>(node: Document | Node, predicate: (testNode: Node) => testNode is T): void { | ||
>visitNodes : <T extends Node>(node: Document | Node, predicate: (testNode: Node) => testNode is T) => void | ||
>node : Node | Document | ||
>predicate : (testNode: Node) => testNode is T | ||
>testNode : Node | ||
|
||
isNode(node) && predicate(node); | ||
>isNode(node) && predicate(node) : boolean | ||
>isNode(node) : boolean | ||
>isNode : (node: unknown) => node is Node | ||
>node : Node | Document | ||
>predicate(node) : boolean | ||
>predicate : (testNode: Node) => testNode is T | ||
>node : Node | ||
|
||
if (!isNode(node) || !isBar(node)) { | ||
>!isNode(node) || !isBar(node) : boolean | ||
>!isNode(node) : boolean | ||
>isNode(node) : boolean | ||
>isNode : (node: unknown) => node is Node | ||
>node : Node | Document | ||
>!isBar(node) : boolean | ||
>isBar(node) : boolean | ||
>isBar : (node: Node) => node is BarNode | ||
>node : Node | ||
|
||
const nodes: Node[] = node.children; | ||
>nodes : Node[] | ||
>node.children : Node[] | ||
>node : FooNode | Document | ||
>children : Node[] | ||
} | ||
} | ||
|
||
// Repro from #53311 | ||
|
||
type A = { a: string }; | ||
>A : { a: string; } | ||
>a : string | ||
|
||
type B = { b: string }; | ||
>B : { b: string; } | ||
>b : string | ||
|
||
function f1<T extends A | B>(t: T, x: A | B) { | ||
>f1 : <T extends A | B>(t: T, x: A | B) => void | ||
>t : T | ||
>x : A | B | ||
|
||
const a = [t, x]; // (A | B)[] by subtype reduction | ||
>a : (A | B)[] | ||
>[t, x] : (A | B)[] | ||
>t : T | ||
>x : A | B | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// @strict: true | ||
// @noEmit: true | ||
|
||
// Repro from #53311 | ||
|
||
type FooNode = { | ||
kind: 'foo'; | ||
children: Node[]; | ||
}; | ||
|
||
type BarNode = { | ||
kind: 'bar'; | ||
} | ||
|
||
type Node = FooNode | BarNode; | ||
|
||
type Document = { | ||
kind: 'document'; | ||
children: Node[]; | ||
}; | ||
|
||
declare function isNode(node: unknown): node is Node; | ||
declare function isBar(node: Node): node is BarNode; | ||
|
||
export function visitNodes<T extends Node>(node: Document | Node, predicate: (testNode: Node) => testNode is T): void { | ||
isNode(node) && predicate(node); | ||
if (!isNode(node) || !isBar(node)) { | ||
const nodes: Node[] = node.children; | ||
} | ||
} | ||
|
||
// Repro from #53311 | ||
|
||
type A = { a: string }; | ||
type B = { b: string }; | ||
|
||
function f1<T extends A | B>(t: T, x: A | B) { | ||
const a = [t, x]; // (A | B)[] by subtype reduction | ||
} |