File: coAndContraVariantInferences2.ts

package info (click to toggle)
node-typescript 5.0.4%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 459,140 kB
  • sloc: javascript: 1,972,754; makefile: 6; sh: 1
file content (120 lines) | stat: -rw-r--r-- 3,444 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// @strict: true

interface A { a: string }
interface B extends A { b: string }
interface C extends A { c: string }

declare function cast<T, U extends T>(x: T, test: (x: T) => x is U): U;

declare function isC(x: A): x is C;

function f1(a: A, b: B) {
    const x1 = cast(a, isC);  // cast<A, C>
    const x2 = cast(b, isC);  // cast<A, C>
}

declare function useA(a: A): void;

declare function consume<T, U extends T>(t: T, u: U, f: (x: T) => void): void;

function f2(b: B, c: C) {
    consume(b, c, useA);  // consume<A, C>
    consume(c, b, useA);  // consume<A, B>
    consume(b, b, useA);  // consume<B, B>
    consume(c, c, useA);  // consume<C, C>
}

declare function every<T, U extends T>(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 {
    Block,
    Identifier,
    CaseClause,
    FunctionExpression,
    FunctionDeclaration,
}

interface Node { kind: SyntaxKind; }
interface Expression extends Node { _expressionBrand: any; }
interface Declaration extends Node { _declarationBrand: any; }
interface Block extends Node { kind: SyntaxKind.Block; }
interface Identifier extends Expression, Declaration { kind: SyntaxKind.Identifier; }
interface CaseClause extends Node { kind: SyntaxKind.CaseClause; }
interface FunctionDeclaration extends Declaration { kind: SyntaxKind.FunctionDeclaration; }

type HasLocals = Block | FunctionDeclaration;
declare function canHaveLocals(node: Node): node is HasLocals;

declare function assertNode<T extends Node, U extends T>(node: T | undefined, test: (node: T) => node is U): asserts node is U;
declare function assertNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined): void;

function foo(node: FunctionDeclaration | CaseClause) {
    assertNode(node, canHaveLocals);  // assertNode<Node, HasLocals>
    node;  // FunctionDeclaration
}

declare function isExpression(node: Node): node is Expression;

declare function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut;

function bar(node: Identifier | FunctionDeclaration) {
    const a = tryCast(node, isExpression);  // tryCast<Expression, Node>
}

// Repro from #49924

const enum SyntaxKind1 {
    ClassExpression,
    ClassStatement,
}

interface Node1 {
    kind: SyntaxKind1;
}

interface Statement1 extends Node1 {
    _statementBrand: any;
}

interface ClassExpression1 extends Node1 {
    kind: SyntaxKind1.ClassExpression;
}

interface ClassStatement1 extends Statement1 {
    kind: SyntaxKind1.ClassStatement;
}

type ClassLike1 = ClassExpression1 | ClassStatement1;

declare function isClassLike(node: Node1): node is ClassLike1;

declare const statement: Statement1 | undefined;

const maybeClassStatement = tryCast(statement, isClassLike);  // ClassLike1

// Repro from #49924

interface TypeNode extends Node {
    typeInfo: string;
}

interface NodeArray<T extends Node> extends Array<T> {
    someProp: string;
}

declare function isNodeArray<T extends Node>(array: readonly T[]): array is NodeArray<T>;

declare const types: readonly TypeNode[];

const x = tryCast(types, isNodeArray);  // NodeAray<TypeNode>