File: reverseMappedPartiallyInferableTypes.ts

package info (click to toggle)
node-typescript 4.9.5%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 533,908 kB
  • sloc: javascript: 2,018,330; makefile: 7; sh: 1
file content (128 lines) | stat: -rw-r--r-- 2,522 bytes parent folder | download | duplicates (4)
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
121
122
123
124
125
126
127
128
// @strict: true

// Repro from #30505

export type Prop<T> = { (): T }
export type PropType<T> = Prop<T>;
export type PropDefaultValue<T> = T;


export type PropValidatorFunction<T> = (value: T) => boolean;
export type PropValidator<T> = PropOptions<T>;


export type PropOptions<T> = {
    type: PropType<T>;

    value?: PropDefaultValue<T>,
    required?: boolean;
    validator?: PropValidatorFunction<T>;
}

export type RecordPropsDefinition<T> = {
    [K in keyof T]: PropValidator<T[K]>
}
export type PropsDefinition<T> = RecordPropsDefinition<T>;


declare function extend<T>({ props }: { props: PropsDefinition<T> }):  PropsDefinition<T>;

interface MyType {
    valid: boolean;
}

const r = extend({
    props: {
        notResolved: {
            type: Object as PropType<MyType>,
            validator: x => {
                return x.valid;
            }
        },
        explicit: {
            type: Object as PropType<MyType>,
            validator: (x: MyType) => {
                return x.valid;
            }
        }
    }
})

r.explicit
r.notResolved
r.explicit.required
r.notResolved.required

// Modified repro from #30505

type Box<T> = {
    contents?: T;
    contains?(content: T): boolean;
};

type Mapped<T> = {
    [K in keyof T]: Box<T[K]>;
}

declare function id<T>(arg: Mapped<T>): Mapped<T>;

// All properties have inferable types

const obj1 = id({
    foo: {
        contents: ""
    }
});

// Some properties have inferable types

const obj2 = id({
    foo: {
        contents: "",
        contains(k) {
            return k.length > 0;
        }
    }
});

// No properties have inferable types

const obj3 = id({
    foo: {
        contains(k) {
            return k.length > 0;
        }
    }
});

// Repros from #40809

type Mapped1<T> = {
    [K in keyof T]: [T[K], (arg: T) => boolean];
};

declare function inferMapped1<T>(arg: Mapped1<T>): void;

inferMapped1({
    key: [3, arg => arg.key > 5]
});

type Mapped2<T> = {
    [K in keyof T]: [T[K], unknown extends T ? unknown : (arg: T) => boolean];
};

declare function inferMapped2<T>(arg: Mapped2<T>): void;

inferMapped2({
    key: [3, arg => arg.key > 5]
});

type MappedReadonly<T> = {
    readonly [K in keyof T]: readonly [T[K], (arg: T) => boolean];
};

declare function inferMappedReadonly<T>(arg: MappedReadonly<T>): void;

inferMappedReadonly({
    key: [3, arg => arg.key > 5]
});