import { Data, IfAny } 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 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 [(infer U)[] | { type: (infer U)[] }] ? U extends DateConstructor ? Date | InferPropType : InferPropType : [T] extends [Prop] ? unknown extends V ? IfAny : V : 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 } : {}