vue/types/v3-component-props.d.ts

100 lines
3.0 KiB
TypeScript

import { Data, IfAny } from './common'
export type ComponentPropsOptions<P = Data> =
| ComponentObjectPropsOptions<P>
| string[]
export type ComponentObjectPropsOptions<P = Data> = {
[K in keyof P]: Prop<P[K]> | null
}
export type Prop<T, D = T> = PropOptions<T, D> | PropType<T>
type DefaultFactory<T> = () => T | null | undefined
export interface PropOptions<T = any, D = T> {
type?: PropType<T> | true | null
required?: boolean
default?: D | DefaultFactory<D> | null | undefined | object
validator?(value: unknown): boolean
}
export type PropType<T> = PropConstructor<T> | PropConstructor<T>[]
type PropConstructor<T> =
| { (): T }
| { new (...args: never[]): T & object }
| { new (...args: string[]): Function }
type RequiredKeys<T> = {
[K in keyof T]: T[K] extends
| { required: true }
| { default: any }
| BooleanConstructor
| { type: BooleanConstructor }
? K
: never
}[keyof T]
type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>
type ExtractFunctionPropType<
T extends Function,
TArgs extends Array<any> = any[],
TResult = any
> = T extends (...args: TArgs) => TResult ? T : never
type ExtractCorrectPropType<T> = T extends Function
? ExtractFunctionPropType<T>
: Exclude<T, Function>
type InferPropType<T> = [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<string, any>
: [T] extends [BooleanConstructor | { type: BooleanConstructor }]
? boolean
: [T] extends [DateConstructor | { type: DateConstructor }]
? Date
: [T] extends [(infer U)[] | { type: (infer U)[] }]
? U extends DateConstructor
? Date | InferPropType<U>
: InferPropType<U>
: [T] extends [Prop<infer V, infer D>]
? unknown extends V
? IfAny<V, V, D>
: V
: T
export type ExtractPropTypes<O> = {
// use `keyof Pick<O, RequiredKeys<O>>` instead of `RequiredKeys<O>` to support IDE features
[K in keyof Pick<O, RequiredKeys<O>>]: InferPropType<O[K]>
} & {
// use `keyof Pick<O, OptionalKeys<O>>` instead of `OptionalKeys<O>` to support IDE features
[K in keyof Pick<O, OptionalKeys<O>>]?: InferPropType<O[K]>
}
type DefaultKeys<T> = {
[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> = O extends object
? // use `keyof Pick<O, DefaultKeys<O>>` instead of `DefaultKeys<O>` to support IDE features
{ [K in keyof Pick<O, DefaultKeys<O>>]: InferPropType<O[K]> }
: {}