mirror of https://github.com/vuejs/core.git
types: fix withDefaults type
This commit is contained in:
parent
623ba514ec
commit
f703a11a43
|
@ -19,7 +19,7 @@ describe('defineProps w/ type declaration', () => {
|
|||
const props = defineProps<{
|
||||
foo: string
|
||||
bool?: boolean
|
||||
boolAndUndefined: boolean | undefined
|
||||
boolOrUndefined: boolean | undefined
|
||||
}>()
|
||||
// explicitly declared type should be refined
|
||||
expectType<string>(props.foo)
|
||||
|
@ -27,7 +27,7 @@ describe('defineProps w/ type declaration', () => {
|
|||
props.bar
|
||||
|
||||
expectType<boolean>(props.bool)
|
||||
expectType<boolean>(props.boolAndUndefined)
|
||||
expectType<boolean>(props.boolOrUndefined)
|
||||
})
|
||||
|
||||
describe('defineProps w/ generics', () => {
|
||||
|
@ -52,7 +52,8 @@ describe('defineProps w/ type declaration + withDefaults', () => {
|
|||
y?: string
|
||||
z?: string
|
||||
bool?: boolean
|
||||
boolAndUndefined: boolean | undefined
|
||||
boolOrUndefined: boolean | undefined
|
||||
defaultUndefined?: string
|
||||
}>(),
|
||||
{
|
||||
number: 123,
|
||||
|
@ -61,10 +62,14 @@ describe('defineProps w/ type declaration + withDefaults', () => {
|
|||
fn: () => {},
|
||||
genStr: () => '',
|
||||
y: undefined,
|
||||
z: 'string'
|
||||
z: 'string',
|
||||
defaultUndefined: undefined as string | undefined
|
||||
}
|
||||
)
|
||||
|
||||
// @ts-expect-error
|
||||
res.number++
|
||||
|
||||
res.number + 1
|
||||
res.arr.push('hi')
|
||||
res.obj.x
|
||||
|
@ -75,12 +80,21 @@ describe('defineProps w/ type declaration + withDefaults', () => {
|
|||
// @ts-expect-error
|
||||
res.y.slice()
|
||||
|
||||
expectType<string | undefined>(res.x)
|
||||
expectType<string | undefined>(res.y)
|
||||
expectType<string>(res.z)
|
||||
|
||||
expectType<boolean>(res.bool)
|
||||
expectType<boolean>(res.boolAndUndefined)
|
||||
type T = {
|
||||
number: number
|
||||
arr: string[]
|
||||
obj: { x: number }
|
||||
fn: (e: string) => void
|
||||
genStr: string
|
||||
x: string | undefined
|
||||
y: string | undefined
|
||||
z: string
|
||||
bool: boolean
|
||||
boolOrUndefined: boolean
|
||||
defaultUndefined: string | undefined
|
||||
}
|
||||
expectType<T>(res)
|
||||
expectType<typeof res>({} as T)
|
||||
})
|
||||
|
||||
describe('defineProps w/ union type declaration + withDefaults', () => {
|
||||
|
@ -127,6 +141,9 @@ describe('defineProps w/ generic type declaration + withDefaults', <T extends
|
|||
|
||||
res.n + 1
|
||||
|
||||
// @ts-expect-error readonly
|
||||
res.n++
|
||||
|
||||
expectType<T[] | { x: T }>(res.generic1)
|
||||
expectType<{ x: T }>(res.generic2)
|
||||
expectType<TString>(res.generic3)
|
||||
|
|
|
@ -293,23 +293,31 @@ type InferDefault<P, T> =
|
|||
| ((props: P) => T & {})
|
||||
| (T extends NativeType ? T : never)
|
||||
|
||||
type NonPartial<T> = {
|
||||
[K in keyof Required<T>]: T[K]
|
||||
}
|
||||
|
||||
type UndefinedDefault<T, Default> = Default extends undefined
|
||||
? T
|
||||
: NotUndefined<T>
|
||||
|
||||
type PropsWithDefaults<
|
||||
T,
|
||||
Defaults extends InferDefaults<T>,
|
||||
BKeys extends keyof T
|
||||
> = Omit<T, keyof Defaults> & {
|
||||
[K in keyof Defaults]-?: K extends keyof T
|
||||
? Defaults[K] extends undefined
|
||||
? T[K]
|
||||
: NotUndefined<T[K]>
|
||||
: never
|
||||
} & {
|
||||
readonly [K in BKeys]-?: K extends keyof Defaults
|
||||
? Defaults[K] extends undefined
|
||||
? boolean | undefined
|
||||
> = Readonly<
|
||||
NonPartial<Omit<T, keyof (Defaults | BKeys)>> & {
|
||||
[K in keyof Defaults]-?: K extends keyof T
|
||||
? UndefinedDefault<T[K], Defaults[K]>
|
||||
: never
|
||||
} & {
|
||||
[K in BKeys]: K extends keyof Defaults
|
||||
? Defaults[K] extends undefined
|
||||
? boolean | undefined
|
||||
: boolean
|
||||
: boolean
|
||||
: boolean
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
/**
|
||||
* Vue `<script setup>` compiler macro for providing props default values when
|
||||
|
|
Loading…
Reference in New Issue