fix(types): declared prop keys should always exist in props argument (#3726)

This commit is contained in:
GU Yiling 2021-05-13 05:47:31 +08:00 committed by GitHub
parent f01aadf2a1
commit 9b160b9405
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 5 deletions

View File

@ -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<
UnionToIntersection<ExtractOptionProp<Mixin>> & LooseRequired<
UnionToIntersection<ExtractOptionProp<Extends>>, Props &
UnionToIntersection<ExtractOptionProp<Mixin>> &
UnionToIntersection<ExtractOptionProp<Extends>>
>
>,
ctx: SetupContext<E> ctx: SetupContext<E>
) => Promise<RawBindings> | RawBindings | RenderFunction | void ) => Promise<RawBindings> | RawBindings | RenderFunction | void
name?: string name?: string

View File

@ -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] }

View File

@ -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),