| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import {
- type ComputedRef,
- type MaybeRef,
- type Ref,
- computed,
- defineComponent,
- defineModel,
- reactive,
- ref,
- shallowRef,
- watch,
- } from 'vue'
- import { expectType } from './utils'
- const source = ref('foo')
- const source2 = computed(() => source.value)
- const source3 = () => 1
- type Bar = Ref<string> | ComputedRef<string> | (() => number)
- type Foo = readonly [Ref<string>, ComputedRef<string>, () => number]
- type OnCleanup = (fn: () => void) => void
- const readonlyArr: Foo = [source, source2, source3]
- // lazy watcher will have consistent types for oldValue.
- watch(source, (value, oldValue, onCleanup) => {
- expectType<string>(value)
- expectType<string>(oldValue)
- expectType<OnCleanup>(onCleanup)
- })
- watch([source, source2, source3], (values, oldValues) => {
- expectType<[string, string, number]>(values)
- expectType<[string, string, number]>(oldValues)
- })
- // const array
- watch([source, source2, source3] as const, (values, oldValues) => {
- expectType<Readonly<[string, string, number]>>(values)
- expectType<Readonly<[string, string, number]>>(oldValues)
- })
- // reactive array
- watch(reactive([source, source2, source3]), (value, oldValues) => {
- expectType<Bar[]>(value)
- expectType<Bar[]>(oldValues)
- })
- // reactive w/ readonly tuple
- watch(reactive([source, source2, source3] as const), (value, oldValues) => {
- expectType<Foo>(value)
- expectType<Foo>(oldValues)
- })
- // readonly array
- watch(readonlyArr, (values, oldValues) => {
- expectType<Readonly<[string, string, number]>>(values)
- expectType<Readonly<[string, string, number]>>(oldValues)
- })
- // no type error, case from vueuse
- declare const aAny: any
- watch(aAny, (v, ov) => {})
- watch(aAny, (v, ov) => {}, { immediate: true })
- // immediate watcher's oldValue will be undefined on first run.
- watch(
- source,
- (value, oldValue) => {
- expectType<string>(value)
- expectType<string | undefined>(oldValue)
- },
- { immediate: true },
- )
- watch(
- [source, source2, source3],
- (values, oldValues) => {
- expectType<[string, string, number]>(values)
- expectType<[string | undefined, string | undefined, number | undefined]>(
- oldValues,
- )
- },
- { immediate: true },
- )
- // const array
- watch(
- [source, source2, source3] as const,
- (values, oldValues) => {
- expectType<Readonly<[string, string, number]>>(values)
- expectType<
- Readonly<[string | undefined, string | undefined, number | undefined]>
- >(oldValues)
- },
- { immediate: true },
- )
- // reactive array
- watch(
- reactive([source, source2, source3]),
- (value, oldVals) => {
- expectType<Bar[]>(value)
- expectType<Bar[] | undefined>(oldVals)
- },
- { immediate: true },
- )
- // reactive w/ readonly tuple
- watch(reactive([source, source2, source3] as const), (value, oldVals) => {
- expectType<Foo>(value)
- expectType<Foo | undefined>(oldVals)
- })
- // readonly array
- watch(
- readonlyArr,
- (values, oldValues) => {
- expectType<Readonly<[string, string, number]>>(values)
- expectType<
- Readonly<[string | undefined, string | undefined, number | undefined]>
- >(oldValues)
- },
- { immediate: true },
- )
- // should provide correct ref.value inner type to callbacks
- const nestedRefSource = ref({
- foo: ref(1),
- })
- watch(nestedRefSource, (v, ov) => {
- expectType<{ foo: number }>(v)
- expectType<{ foo: number }>(ov)
- })
- const someRef = ref({ test: 'test' })
- const otherRef = ref({ a: 'b' })
- watch([someRef, otherRef], values => {
- const value1 = values[0]
- // no type error
- console.log(value1.test)
- const value2 = values[1]
- // no type error
- console.log(value2.a)
- })
- // #6135
- defineComponent({
- data() {
- return { a: 1 }
- },
- created() {
- this.$watch(
- () => this.a,
- (v, ov, onCleanup) => {
- expectType<number>(v)
- expectType<number>(ov)
- expectType<OnCleanup>(onCleanup)
- },
- )
- },
- })
- {
- //#7852
- type Steps = { step: '1' } | { step: '2' }
- const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
- const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
- watch(shallowUnionGenParam, value => {
- expectType<Steps>(value)
- })
- watch(shallowUnionAsCast, value => {
- expectType<Steps>(value)
- })
- }
- {
- // defineModel
- const bool = defineModel({ default: false })
- watch(bool, value => {
- expectType<boolean>(value)
- })
- const bool1 = defineModel<boolean>()
- watch(bool1, value => {
- expectType<boolean | undefined>(value)
- })
- const msg = defineModel<string>({ required: true })
- watch(msg, value => {
- expectType<string>(value)
- })
- const arr = defineModel<string[]>({ required: true })
- watch(arr, value => {
- expectType<string[]>(value)
- })
- const obj = defineModel<{ foo: string }>({ required: true })
- watch(obj, value => {
- expectType<{ foo: string }>(value)
- })
- }
- {
- const css: MaybeRef<string> = ''
- watch(ref(css), value => {
- expectType<string>(value)
- })
- }
|