fix(types): declared prop keys should always exist in props
argument (#3726)
This commit is contained in:
parent
f01aadf2a1
commit
9b160b9405
@ -65,7 +65,7 @@ import {
|
|||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
import { VNodeChild } from './vnode'
|
import { VNodeChild } from './vnode'
|
||||||
import { callWithAsyncErrorHandling } from './errorHandling'
|
import { callWithAsyncErrorHandling } from './errorHandling'
|
||||||
import { UnionToIntersection } from './helpers/typeUtils'
|
import { LooseRequired, UnionToIntersection } from './helpers/typeUtils'
|
||||||
import { deepMergeData } from './compat/data'
|
import { deepMergeData } from './compat/data'
|
||||||
import { DeprecationTypes } from './compat/compatConfig'
|
import { DeprecationTypes } from './compat/compatConfig'
|
||||||
import {
|
import {
|
||||||
@ -130,9 +130,13 @@ export interface ComponentOptionsBase<
|
|||||||
ComponentCustomOptions {
|
ComponentCustomOptions {
|
||||||
setup?: (
|
setup?: (
|
||||||
this: void,
|
this: void,
|
||||||
props: Props &
|
props: Readonly<
|
||||||
|
LooseRequired<
|
||||||
|
Props &
|
||||||
UnionToIntersection<ExtractOptionProp<Mixin>> &
|
UnionToIntersection<ExtractOptionProp<Mixin>> &
|
||||||
UnionToIntersection<ExtractOptionProp<Extends>>,
|
UnionToIntersection<ExtractOptionProp<Extends>>
|
||||||
|
>
|
||||||
|
>,
|
||||||
ctx: SetupContext<E>
|
ctx: SetupContext<E>
|
||||||
) => Promise<RawBindings> | RawBindings | RenderFunction | void
|
) => Promise<RawBindings> | RawBindings | RenderFunction | void
|
||||||
name?: string
|
name?: string
|
||||||
|
@ -3,3 +3,6 @@ export type UnionToIntersection<U> = (U extends any
|
|||||||
: never) extends ((k: infer I) => void)
|
: never) extends ((k: infer I) => void)
|
||||||
? I
|
? I
|
||||||
: never
|
: never
|
||||||
|
|
||||||
|
// make keys required but keep undefined values
|
||||||
|
export type LooseRequired<T> = { [P in string & keyof T]: T[P] }
|
||||||
|
@ -9,7 +9,8 @@ import {
|
|||||||
expectType,
|
expectType,
|
||||||
ShallowUnwrapRef,
|
ShallowUnwrapRef,
|
||||||
FunctionalComponent,
|
FunctionalComponent,
|
||||||
ComponentPublicInstance
|
ComponentPublicInstance,
|
||||||
|
toRefs
|
||||||
} from './index'
|
} from './index'
|
||||||
|
|
||||||
declare function extractComponentOptions<Props, RawBindings>(
|
declare function extractComponentOptions<Props, RawBindings>(
|
||||||
@ -42,6 +43,27 @@ describe('object props', () => {
|
|||||||
object?: object
|
object?: object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ExpectedRefs {
|
||||||
|
a: Ref<number | undefined>
|
||||||
|
b: Ref<string>
|
||||||
|
e: Ref<Function | undefined>
|
||||||
|
bb: Ref<string>
|
||||||
|
bbb: Ref<string>
|
||||||
|
cc: Ref<string[] | undefined>
|
||||||
|
dd: Ref<{ n: 1 }>
|
||||||
|
ee: Ref<(() => string) | undefined>
|
||||||
|
ff: Ref<((a: number, b: string) => { a: boolean }) | undefined>
|
||||||
|
ccc: Ref<string[] | undefined>
|
||||||
|
ddd: Ref<string[]>
|
||||||
|
eee: Ref<() => { a: string }>
|
||||||
|
fff: Ref<(a: number, b: string) => { a: boolean }>
|
||||||
|
hhh: Ref<boolean>
|
||||||
|
ggg: Ref<'foo' | 'bar'>
|
||||||
|
ffff: Ref<(a: number, b: string) => { a: boolean }>
|
||||||
|
validated: Ref<string | undefined>
|
||||||
|
object: Ref<object | undefined>
|
||||||
|
}
|
||||||
|
|
||||||
describe('defineComponent', () => {
|
describe('defineComponent', () => {
|
||||||
const MyComponent = defineComponent({
|
const MyComponent = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@ -111,6 +133,26 @@ describe('object props', () => {
|
|||||||
object: Object as PropType<object>
|
object: Object as PropType<object>
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
const refs = toRefs(props)
|
||||||
|
expectType<ExpectedRefs['a']>(refs.a)
|
||||||
|
expectType<ExpectedRefs['b']>(refs.b)
|
||||||
|
expectType<ExpectedRefs['e']>(refs.e)
|
||||||
|
expectType<ExpectedRefs['bb']>(refs.bb)
|
||||||
|
expectType<ExpectedRefs['bbb']>(refs.bbb)
|
||||||
|
expectType<ExpectedRefs['cc']>(refs.cc)
|
||||||
|
expectType<ExpectedRefs['dd']>(refs.dd)
|
||||||
|
expectType<ExpectedRefs['ee']>(refs.ee)
|
||||||
|
expectType<ExpectedRefs['ff']>(refs.ff)
|
||||||
|
expectType<ExpectedRefs['ccc']>(refs.ccc)
|
||||||
|
expectType<ExpectedRefs['ddd']>(refs.ddd)
|
||||||
|
expectType<ExpectedRefs['eee']>(refs.eee)
|
||||||
|
expectType<ExpectedRefs['fff']>(refs.fff)
|
||||||
|
expectType<ExpectedRefs['hhh']>(refs.hhh)
|
||||||
|
expectType<ExpectedRefs['ggg']>(refs.ggg)
|
||||||
|
expectType<ExpectedRefs['ffff']>(refs.ffff)
|
||||||
|
expectType<ExpectedRefs['validated']>(refs.validated)
|
||||||
|
expectType<ExpectedRefs['object']>(refs.object)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setupA: 1,
|
setupA: 1,
|
||||||
setupB: ref(1),
|
setupB: ref(1),
|
||||||
|
Loading…
Reference in New Issue
Block a user