mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
100 lines
3.0 KiB
TypeScript
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]> }
|
|
: {}
|