/
reverseMappedPartiallyInferableTypes.ts
96 lines (73 loc) · 1.8 KB
/
reverseMappedPartiallyInferableTypes.ts
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
// @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;
}
}
});