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 { VNodeChild } from './vnode'
|
||||
import { callWithAsyncErrorHandling } from './errorHandling'
|
||||
import { UnionToIntersection } from './helpers/typeUtils'
|
||||
import { LooseRequired, UnionToIntersection } from './helpers/typeUtils'
|
||||
import { deepMergeData } from './compat/data'
|
||||
import { DeprecationTypes } from './compat/compatConfig'
|
||||
import {
|
||||
@ -130,9 +130,13 @@ export interface ComponentOptionsBase<
|
||||
ComponentCustomOptions {
|
||||
setup?: (
|
||||
this: void,
|
||||
props: Props &
|
||||
UnionToIntersection<ExtractOptionProp<Mixin>> &
|
||||
UnionToIntersection<ExtractOptionProp<Extends>>,
|
||||
props: Readonly<
|
||||
LooseRequired<
|
||||
Props &
|
||||
UnionToIntersection<ExtractOptionProp<Mixin>> &
|
||||
UnionToIntersection<ExtractOptionProp<Extends>>
|
||||
>
|
||||
>,
|
||||
ctx: SetupContext<E>
|
||||
) => Promise<RawBindings> | RawBindings | RenderFunction | void
|
||||
name?: string
|
||||
|
@ -3,3 +3,6 @@ export type UnionToIntersection<U> = (U extends any
|
||||
: never) extends ((k: infer I) => void)
|
||||
? I
|
||||
: 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,
|
||||
ShallowUnwrapRef,
|
||||
FunctionalComponent,
|
||||
ComponentPublicInstance
|
||||
ComponentPublicInstance,
|
||||
toRefs
|
||||
} from './index'
|
||||
|
||||
declare function extractComponentOptions<Props, RawBindings>(
|
||||
@ -42,6 +43,27 @@ describe('object props', () => {
|
||||
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', () => {
|
||||
const MyComponent = defineComponent({
|
||||
props: {
|
||||
@ -111,6 +133,26 @@ describe('object props', () => {
|
||||
object: Object as PropType<object>
|
||||
},
|
||||
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 {
|
||||
setupA: 1,
|
||||
setupB: ref(1),
|
||||
|
Loading…
Reference in New Issue
Block a user