File: propTypeValidatorInference.js

package info (click to toggle)
node-typescript 4.9.5%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 533,908 kB
  • sloc: javascript: 2,018,330; makefile: 7; sh: 1
file content (121 lines) | stat: -rw-r--r-- 3,872 bytes parent folder | download | duplicates (3)
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
//// [tests/cases/compiler/propTypeValidatorInference.ts] ////

//// [index.d.ts]
export const nominalTypeHack: unique symbol;

export type IsOptional<T> = undefined | null extends T ? true : undefined extends T ? true : null extends T ? true : false;

export type RequiredKeys<V> = { [K in keyof V]-?: Exclude<V[K], undefined> extends Validator<infer T> ? IsOptional<T> extends true ? never : K : never }[keyof V];
export type OptionalKeys<V> = Exclude<keyof V, RequiredKeys<V>>;
export type InferPropsInner<V> = { [K in keyof V]-?: InferType<V[K]>; };

export interface Validator<T> {
    (props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null;
    [nominalTypeHack]?: T;
}

export interface Requireable<T> extends Validator<T> {
    isRequired: Validator<NonNullable<T>>;
}

export type ValidationMap<T> = { [K in keyof T]?: Validator<T[K]> };

export type InferType<V> = V extends Validator<infer T> ? T : any;
export type InferProps<V> =
    & InferPropsInner<Pick<V, RequiredKeys<V>>>
    & Partial<InferPropsInner<Pick<V, OptionalKeys<V>>>>;

export const any: Requireable<any>;
export const array: Requireable<any[]>;
export const bool: Requireable<boolean>;
export const string: Requireable<string>;
export const number: Requireable<number>;
export function shape<P extends ValidationMap<any>>(type: P): Requireable<InferProps<P>>;
export function oneOfType<T extends Validator<any>>(types: T[]): Requireable<NonNullable<InferType<T>>>;


//// [file.ts]
import * as PropTypes from "prop-types";
interface Props {
    any?: any;
    array: string[];
    bool: boolean;
    shape: {
        foo: string;
        bar?: boolean;
        baz?: any
    };
    oneOfType: string | boolean | {
        foo?: string;
        bar: number;
    };
}

type PropTypesMap = PropTypes.ValidationMap<Props>;

const innerProps = {
    foo: PropTypes.string.isRequired,
    bar: PropTypes.bool,
    baz: PropTypes.any
};

const arrayOfTypes = [PropTypes.string, PropTypes.bool, PropTypes.shape({
    foo: PropTypes.string,
    bar: PropTypes.number.isRequired
})];

// TS checking
const propTypes: PropTypesMap = {
    any: PropTypes.any,
    array: PropTypes.array.isRequired,
    bool: PropTypes.bool.isRequired,
    shape: PropTypes.shape(innerProps).isRequired,
    oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
};

// JS checking
const propTypesWithoutAnnotation = {
    any: PropTypes.any,
    array: PropTypes.array.isRequired,
    bool: PropTypes.bool.isRequired,
    shape: PropTypes.shape(innerProps).isRequired,
    oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
};

type ExtractedProps = PropTypes.InferProps<typeof propTypes>;

type ExtractedPropsWithoutAnnotation = PropTypes.InferProps<typeof propTypesWithoutAnnotation>;

type ExtractPropsMatch = ExtractedProps extends ExtractedPropsWithoutAnnotation ? true : false;
const x: true = (null as any as ExtractPropsMatch);

//// [file.js]
"use strict";
exports.__esModule = true;
var PropTypes = require("prop-types");
var innerProps = {
    foo: PropTypes.string.isRequired,
    bar: PropTypes.bool,
    baz: PropTypes.any
};
var arrayOfTypes = [PropTypes.string, PropTypes.bool, PropTypes.shape({
        foo: PropTypes.string,
        bar: PropTypes.number.isRequired
    })];
// TS checking
var propTypes = {
    any: PropTypes.any,
    array: PropTypes.array.isRequired,
    bool: PropTypes.bool.isRequired,
    shape: PropTypes.shape(innerProps).isRequired,
    oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired
};
// JS checking
var propTypesWithoutAnnotation = {
    any: PropTypes.any,
    array: PropTypes.array.isRequired,
    bool: PropTypes.bool.isRequired,
    shape: PropTypes.shape(innerProps).isRequired,
    oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired
};
var x = null;