import { Data } from './common' export type ComponentPropsOptions

= | ComponentObjectPropsOptions

| string[] export type ComponentObjectPropsOptions

= { [K in keyof P]: Prop | null } export type Prop = PropOptions | PropType type DefaultFactory = () => T | null | undefined export interface PropOptions { type?: PropType | true | null required?: boolean default?: D | DefaultFactory | null | undefined | object validator?(value: unknown): boolean } export type PropType = PropConstructor | PropConstructor[] type PropConstructor = | { (): T } | { new (...args: never[]): T & object } | { new (...args: string[]): Function } type RequiredKeys = { [K in keyof T]: T[K] extends | { required: true } | { default: any } | BooleanConstructor | { type: BooleanConstructor } ? K : never }[keyof T] type OptionalKeys = Exclude> type ExtractFunctionPropType< T extends Function, TArgs extends Array = any[], TResult = any > = T extends (...args: TArgs) => TResult ? T : never type ExtractCorrectPropType = T extends Function ? ExtractFunctionPropType : Exclude // prettier-ignore type InferPropType = T extends null ? any // null & true would fail to infer : T extends { type: null | true } ? any // As TS issue https://github.com/Microsoft/TypeScript/issues/14829 // somehow `ObjectConstructor` when inferred from { (): T } becomes `any` // `BooleanConstructor` when inferred from PropConstructor(with PropMethod) becomes `Boolean` : T extends ObjectConstructor | { type: ObjectConstructor } ? Record : T extends BooleanConstructor | { type: BooleanConstructor } ? boolean : T extends DateConstructor | { type: DateConstructor} ? Date : T extends FunctionConstructor ? Function : T extends Prop ? unknown extends V ? D extends null | undefined ? V : D : ExtractCorrectPropType : T export type ExtractPropTypes = { // use `keyof Pick>` instead of `RequiredKeys` to support IDE features [K in keyof Pick>]: InferPropType } & { // use `keyof Pick>` instead of `OptionalKeys` to support IDE features [K in keyof Pick>]?: InferPropType } type DefaultKeys = { [K in keyof T]: T[K] extends | { default: any } | BooleanConstructor | { type: BooleanConstructor } ? T[K] extends { type: BooleanConstructor required: true } ? never : K : never }[keyof T] // extract props which defined with default from prop options export type ExtractDefaultPropTypes = O extends object ? // use `keyof Pick>` instead of `DefaultKeys` to support IDE features { [K in keyof Pick>]: InferPropType } : {}