Skip to content

fix(runtime-core): optional props from Mixin/Extends are treated as r… #2048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions packages/runtime-core/src/apiDefineComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
AllowedComponentProps,
ComponentCustomProps
} from './component'
import { ExtractPropTypes, ComponentPropsOptions } from './componentProps'
import {
ExtractPropTypes,
ComponentPropsOptions,
ExtractDefaultPropTypes
} from './componentProps'
import { EmitsOptions } from './componentEmits'
import { isFunction } from '@vue/shared'
import { VNodeProps } from './vnode'
Expand All @@ -37,32 +41,35 @@ export type DefineComponent<
E extends EmitsOptions = Record<string, any>,
EE extends string = string,
PP = PublicProps,
RequiredProps = Readonly<ExtractPropTypes<PropsOrPropOptions>>,
OptionalProps = Readonly<ExtractPropTypes<PropsOrPropOptions, false>>
Props = Readonly<ExtractPropTypes<PropsOrPropOptions>>,
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>
> = ComponentPublicInstanceConstructor<
CreateComponentPublicInstance<
OptionalProps,
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
PP & OptionalProps
PP & Props,
Defaults,
true
> &
RequiredProps
Props
> &
ComponentOptionsBase<
RequiredProps,
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
EE
EE,
Defaults
> &
PP

Expand Down
72 changes: 61 additions & 11 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ import {
WritableComputedOptions,
toRaw
} from '@vue/reactivity'
import { ComponentObjectPropsOptions, ExtractPropTypes } from './componentProps'
import {
ComponentObjectPropsOptions,
ExtractPropTypes,
ExtractDefaultPropTypes
} from './componentProps'
import { EmitsOptions } from './componentEmits'
import { Directive } from './directives'
import {
Expand Down Expand Up @@ -81,7 +85,8 @@ export interface ComponentOptionsBase<
Mixin extends ComponentOptionsMixin,
Extends extends ComponentOptionsMixin,
E extends EmitsOptions,
EE extends string = string
EE extends string = string,
Defaults = {}
>
extends LegacyOptions<Props, D, C, M, Mixin, Extends>,
ComponentInternalOptions,
Expand Down Expand Up @@ -148,6 +153,8 @@ export interface ComponentOptionsBase<
__isFragment?: never
__isTeleport?: never
__isSuspense?: never

__defaults?: Defaults
}

export type ComponentOptionsWithoutProps<
Expand All @@ -159,8 +166,20 @@ export type ComponentOptionsWithoutProps<
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = EmitsOptions,
EE extends string = string
> = ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE> & {
EE extends string = string,
Defaults = {}
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
EE,
Defaults
> & {
props?: undefined
} & ThisType<
CreateComponentPublicInstance<
Expand All @@ -172,7 +191,9 @@ export type ComponentOptionsWithoutProps<
Mixin,
Extends,
E,
Readonly<Props>
Readonly<Props>,
Defaults,
false
>
>

Expand All @@ -187,7 +208,18 @@ export type ComponentOptionsWithArrayProps<
E extends EmitsOptions = EmitsOptions,
EE extends string = string,
Props = Readonly<{ [key in PropNames]?: any }>
> = ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE> & {
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
EE,
{}
> & {
props: PropNames[]
} & ThisType<
CreateComponentPublicInstance<
Expand All @@ -212,8 +244,20 @@ export type ComponentOptionsWithObjectProps<
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = EmitsOptions,
EE extends string = string,
Props = Readonly<ExtractPropTypes<PropsOptions>>
> = ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE> & {
Props = Readonly<ExtractPropTypes<PropsOptions>>,
Defaults = ExtractDefaultPropTypes<PropsOptions>
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
EE,
Defaults
> & {
props: PropsOptions & ThisType<void>
} & ThisType<
CreateComponentPublicInstance<
Expand All @@ -224,7 +268,10 @@ export type ComponentOptionsWithObjectProps<
M,
Mixin,
Extends,
E
E,
Props,
Defaults,
false
>
>

Expand Down Expand Up @@ -261,6 +308,7 @@ export type ComponentOptionsMixin = ComponentOptionsBase<
any,
any,
any,
any,
any
>

Expand Down Expand Up @@ -347,20 +395,22 @@ interface LegacyOptions<
delimiters?: [string, string]
}

export type OptionTypesKeys = 'P' | 'B' | 'D' | 'C' | 'M'
export type OptionTypesKeys = 'P' | 'B' | 'D' | 'C' | 'M' | 'Defaults'

export type OptionTypesType<
P = {},
B = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {}
M extends MethodOptions = {},
Defaults = {}
> = {
P: P
B: B
D: D
C: C
M: M
Defaults: Defaults
}

const enum OptionTypes {
Expand Down
31 changes: 15 additions & 16 deletions packages/runtime-core/src/componentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,15 @@ type PropMethod<T, TConstructor = any> = T extends (...args: any) => any // if i
? { new (): TConstructor; (): T; readonly prototype: TConstructor } // Create Function like constructor
: never

type RequiredKeys<T, MakeDefaultRequired> = {
[K in keyof T]: T[K] extends
| { required: true }
| (MakeDefaultRequired extends true ? { default: any } : never)
? K
: never
type RequiredKeys<T> = {
[K in keyof T]: T[K] extends { required: true } | { default: any } ? K : never
}[keyof T]

type OptionalKeys<T, MakeDefaultRequired> = Exclude<
keyof T,
RequiredKeys<T, MakeDefaultRequired>
>
type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>

type DefaultKeys<T> = {
[K in keyof T]: T[K] extends { default: any } ? K : never
}[keyof T]

type InferPropType<T> = T extends null
? any // null & true would fail to infer
Expand All @@ -86,19 +83,21 @@ type InferPropType<T> = T extends null
? boolean
: T extends Prop<infer V, infer D> ? (unknown extends V ? D : V) : T

export type ExtractPropTypes<
O,
MakeDefaultRequired extends boolean = true
> = O extends object
? { [K in RequiredKeys<O, MakeDefaultRequired>]: InferPropType<O[K]> } &
{ [K in OptionalKeys<O, MakeDefaultRequired>]?: InferPropType<O[K]> }
export type ExtractPropTypes<O> = O extends object
? { [K in RequiredKeys<O>]: InferPropType<O[K]> } &
{ [K in OptionalKeys<O>]?: InferPropType<O[K]> }
: { [K in string]: any }

const enum BooleanFlags {
shouldCast,
shouldCastTrue
}

// extract props which defined with default from prop options
export type ExtractDefaultPropTypes<O> = O extends object
? { [K in DefaultKeys<O>]: InferPropType<O[K]> }
: {}

type NormalizedProp =
| null
| (PropOptions & {
Expand Down
24 changes: 18 additions & 6 deletions packages/runtime-core/src/componentPublicInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ type MixinToOptionTypes<T> = T extends ComponentOptionsBase<
infer M,
infer Mixin,
infer Extends,
any
any,
any,
infer Defaults
>
? OptionTypesType<P & {}, B & {}, D & {}, C & {}, M & {}> &
? OptionTypesType<P & {}, B & {}, D & {}, C & {}, M & {}, Defaults & {}> &
IntersectionMixin<Mixin> &
IntersectionMixin<Extends>
: never
Expand Down Expand Up @@ -130,14 +132,18 @@ export type CreateComponentPublicInstance<
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = {},
PublicProps = P,
Defaults = {},
MakeDefaultsOptional extends boolean = false,
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>,
PublicP = UnwrapMixinsType<PublicMixin, 'P'> & EnsureNonVoid<P>,
PublicB = UnwrapMixinsType<PublicMixin, 'B'> & EnsureNonVoid<B>,
PublicD = UnwrapMixinsType<PublicMixin, 'D'> & EnsureNonVoid<D>,
PublicC extends ComputedOptions = UnwrapMixinsType<PublicMixin, 'C'> &
EnsureNonVoid<C>,
PublicM extends MethodOptions = UnwrapMixinsType<PublicMixin, 'M'> &
EnsureNonVoid<M>
EnsureNonVoid<M>,
PublicDefaults = UnwrapMixinsType<PublicMixin, 'Defaults'> &
EnsureNonVoid<Defaults>
> = ComponentPublicInstance<
PublicP,
PublicB,
Expand All @@ -146,7 +152,9 @@ export type CreateComponentPublicInstance<
PublicM,
E,
PublicProps,
ComponentOptionsBase<P, B, D, C, M, Mixin, Extends, E>
PublicDefaults,
MakeDefaultsOptional,
ComponentOptionsBase<P, B, D, C, M, Mixin, Extends, E, string, Defaults>
>

// public properties exposed on the proxy, which is used as the render context
Expand All @@ -159,11 +167,15 @@ export type ComponentPublicInstance<
M extends MethodOptions = {},
E extends EmitsOptions = {},
PublicProps = P,
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any>
Defaults = {},
MakeDefaultsOptional extends boolean = false,
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>
> = {
$: ComponentInternalInstance
$data: D
$props: P & PublicProps
$props: MakeDefaultsOptional extends true
? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults>
: P & PublicProps
$attrs: Data
$refs: Data
$slots: Slots
Expand Down
6 changes: 4 additions & 2 deletions packages/runtime-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export {
} from './apiLifecycle'
export { provide, inject } from './apiInject'
export { nextTick } from './scheduler'
export { defineComponent, DefineComponent } from './apiDefineComponent'
export { defineComponent } from './apiDefineComponent'
export { defineAsyncComponent } from './apiAsyncComponent'

// Advanced API ----------------------------------------------------------------
Expand Down Expand Up @@ -166,6 +166,7 @@ export {
ComponentCustomProps,
AllowedComponentProps
} from './component'
export { DefineComponent } from './apiDefineComponent'
export {
ComponentOptions,
ComponentOptionsMixin,
Expand Down Expand Up @@ -198,7 +199,8 @@ export {
PropType,
ComponentPropsOptions,
ComponentObjectPropsOptions,
ExtractPropTypes
ExtractPropTypes,
ExtractDefaultPropTypes
} from './componentProps'
export {
Directive,
Expand Down
Loading