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