[K in keyof P]: Prop<P[K]> | null
}
-export type Prop<T> = PropOptions<T> | PropType<T>
+export type Prop<T, D = T> = PropOptions<T, D> | PropType<T>
type DefaultFactory<T> = () => T | null | undefined
-interface PropOptions<T = any> {
+interface PropOptions<T = any, D = T> {
type?: PropType<T> | true | null
required?: boolean
- default?: T | DefaultFactory<T> | null | undefined
+ default?: D | DefaultFactory<D> | null | undefined
validator?(value: unknown): boolean
}
? Record<string, any>
: T extends BooleanConstructor | { type: BooleanConstructor }
? boolean
- : T extends Prop<infer V> ? V : T
+ : T extends Prop<infer V, infer D> ? (unknown extends V ? D : V) : T
export type ExtractPropTypes<
O,
eee: () => { a: string }
fff: (a: number, b: string) => { a: boolean }
hhh: boolean
+ ggg: 'foo' | 'bar'
validated?: string
}
type: Boolean,
required: true
},
+ // default + type casting
+ ggg: {
+ type: String as PropType<'foo' | 'bar'>,
+ default: 'foo'
+ },
validated: {
type: String,
validator: (val: unknown) => val !== ''
expectType<ExpectedProps['eee']>(props.eee)
expectType<ExpectedProps['fff']>(props.fff)
expectType<ExpectedProps['hhh']>(props.hhh)
+ expectType<ExpectedProps['ggg']>(props.ggg)
expectType<ExpectedProps['validated']>(props.validated)
// @ts-expect-error props should be readonly
expectType<ExpectedProps['eee']>(props.eee)
expectType<ExpectedProps['fff']>(props.fff)
expectType<ExpectedProps['hhh']>(props.hhh)
+ expectType<ExpectedProps['ggg']>(props.ggg)
// @ts-expect-error props should be readonly
expectError((props.a = 1))
expectType<ExpectedProps['eee']>(this.eee)
expectType<ExpectedProps['fff']>(this.fff)
expectType<ExpectedProps['hhh']>(this.hhh)
+ expectType<ExpectedProps['ggg']>(this.ggg)
// @ts-expect-error props on `this` should be readonly
expectError((this.a = 1))
eee={() => ({ a: 'eee' })}
fff={(a, b) => ({ a: a > +b })}
hhh={false}
+ ggg="foo"
// should allow class/style as attrs
class="bar"
style={{ color: 'red' }}
// @ts-expect-error wrong prop types
<MyComponent a={'wrong type'} b="foo" dd={{ n: 1 }} ddd={['foo']} />
)
+ expectError(
+ // @ts-expect-error wrong prop types
+ <MyComponent ggg="baz" />
+ )
// @ts-expect-error
expectError(<MyComponent b="foo" dd={{ n: 'string' }} ddd={['foo']} />)
})