File: typePredicatesInUnion3.ts

package info (click to toggle)
node-typescript 5.1.6%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 492,516 kB
  • sloc: javascript: 2,078,951; makefile: 6; sh: 1
file content (63 lines) | stat: -rw-r--r-- 1,310 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
// @strict: true
// @noEmit: true

// A union of function types is considered a type predicate if at least one constituent is a type
// predicate and the other constituents are matching type predicates or functions returning `false`.

type P1 = (x: unknown) => x is string;
type P2 = (x: unknown) => x is number;

type F1 = (x: unknown) => false;
type F2 = (x: unknown) => boolean;
type F3 = (x: unknown) => string;

function f1(x: unknown, p: P1 | P2) {
    if (p(x)) {
        x;  // string | number
    }
}

function f2(x: unknown, p: P1 | P2 | F1) {
    if (p(x)) {
        x;  // string | number
    }
}

function f3(x: unknown, p: P1 | P2 | F2) {
    if (p(x)) {
        x;  // unknown
    }
}

function f4(x: unknown, p: P1 | P2 | F3) {
    if (p(x)) {
        x;  // unknown
    }
}

// Repro from #54143

type HasAttribute<T> = T & { attribute: number };

class Type1 {
    attribute: number | null = null;
    predicate(): this is HasAttribute<Type1> {
        return true;
    }
}

class Type2 {
    attribute: number | null = null;
    predicate(): boolean {
        return true;
    }
}

function assertType<T>(_val: T) {
}

declare const val: Type1 | Type2;

if (val.predicate()) {
    assertType<number>(val.attribute);  // Error
}