types(defineComponent): fix optional Boolean prop types (#2401)

fix #2338
This commit is contained in:
Carlos Rodrigues 2020-10-19 22:25:55 +01:00 committed by GitHub
parent 8e5cdc0d0e
commit d9ad45ad6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 2 deletions

View File

@ -65,13 +65,28 @@ type PropMethod<T, TConstructor = any> = T extends (...args: any) => any // if i
: never
type RequiredKeys<T> = {
[K in keyof T]: T[K] extends { required: true } | { default: any } ? K : never
[K in keyof T]: T[K] extends
| { required: true }
| { default: any }
// don't mark Boolean props as undefined
| BooleanConstructor
| { type: BooleanConstructor }
? K
: never
}[keyof T]
type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>
type DefaultKeys<T> = {
[K in keyof T]: T[K] extends { default: any } ? K : never
[K in keyof T]: T[K] extends
| { default: any }
// Boolean implicitly defaults to false
| BooleanConstructor
| { type: BooleanConstructor }
? T[K] extends { type: BooleanConstructor; required: true } // not default if Boolean is marked as required
? never
: K
: never
}[keyof T]
type InferPropType<T> = T extends null

View File

@ -19,6 +19,7 @@ describe('with object props', () => {
a?: number | undefined
b: string
e?: Function
h: boolean
bb: string
bbb: string
cc?: string[] | undefined
@ -46,6 +47,7 @@ describe('with object props', () => {
required: true
},
e: Function,
h: Boolean,
// default value should infer type and make it non-void
bb: {
default: 'hello'
@ -108,6 +110,7 @@ describe('with object props', () => {
expectType<ExpectedProps['a']>(props.a)
expectType<ExpectedProps['b']>(props.b)
expectType<ExpectedProps['e']>(props.e)
expectType<ExpectedProps['h']>(props.h)
expectType<ExpectedProps['bb']>(props.bb)
expectType<ExpectedProps['bbb']>(props.bbb)
expectType<ExpectedProps['cc']>(props.cc)
@ -142,6 +145,7 @@ describe('with object props', () => {
expectType<ExpectedProps['a']>(props.a)
expectType<ExpectedProps['b']>(props.b)
expectType<ExpectedProps['e']>(props.e)
expectType<ExpectedProps['h']>(props.h)
expectType<ExpectedProps['bb']>(props.bb)
expectType<ExpectedProps['cc']>(props.cc)
expectType<ExpectedProps['dd']>(props.dd)
@ -161,6 +165,7 @@ describe('with object props', () => {
expectType<ExpectedProps['a']>(this.a)
expectType<ExpectedProps['b']>(this.b)
expectType<ExpectedProps['e']>(this.e)
expectType<ExpectedProps['h']>(this.h)
expectType<ExpectedProps['bb']>(this.bb)
expectType<ExpectedProps['cc']>(this.cc)
expectType<ExpectedProps['dd']>(this.dd)

View File

@ -198,3 +198,29 @@ describe('component w/ props w/ default value', () => {
h(MyComponent, {})
})
// #2338
describe('Boolean prop implicit false', () => {
const MyComponent = defineComponent({
props: {
visible: Boolean
}
})
h(MyComponent, {})
const RequiredComponent = defineComponent({
props: {
visible: {
type: Boolean,
required: true
}
}
})
h(RequiredComponent, {
visible: true
})
// @ts-expect-error
expectError(h(RequiredComponent, {}))
})