在VueReact性类型上指定不同的get/set类型

kokeuurv  于 2023-06-24  发布在  Vue.js
关注(0)|答案(1)|浏览(96)

随着TS 5.1中发布的Variant Accessors,我希望能够创建像这样的可合成对象

export function useRouteQueryParam(param: MaybeRef<string>): WritableComputedRef<string | null>
export function useRouteQueryParam(param: MaybeRef<string>, defaultValue: string): WritableComputedRef<string>
export function useRouteQueryParam(param: MaybeRef<string>, defaultValue?: string): WritableComputedRef<string | null> {
  const paramRef = ref(param)
  const route = useRoute()
  const router = useRouter()

  return computed({
    get() {
      const [value] = asArray(route.query[paramRef.value])

      return value ?? defaultValue ?? null
    },
    set(value) {
      const query = { ...route.query, [paramRef.value]: value }
      router.push({ query })
    },
  })
}

理论上,当调用者提供defaultValue时,它可以为WritableComputedRef使用不同的访问器。get总是返回string,但set仍然应该接受string | null。然而,因为WritableComputedRef的语法只需要一个T,我猜这还不可能实现?

nxagd54h

nxagd54h1#

https://tsplay.dev/wea0ew

import { computed, WritableComputedRef, DebuggerOptions, ComputedGetter, ComputedSetter } from 'vue'

declare class GetSet<G, S> {
    get value(): G;
    set value(value: G | S)
}
interface BiPutedRef<G, S> extends Omit<WritableComputedRef<G>, 'value'>, GetSet<G, S> { }
interface BiPutedOptions<G, S> {
    get: ComputedGetter<G>;
    set: ComputedSetter<G | S>;
}

export function biputed<G, S = never>(
    options: BiPutedOptions<G, S>,
    debugOptions?: DebuggerOptions,
): BiPutedRef<G, Exclude<S, G>> {
    return computed(options, debugOptions);
}

;; let r = biputed({
    // ^?
    // let r: BiPutedRef<number, string>
    get() { return 123 },
    set(v: number | string) { }
})

let a = r.value
//  ^?
// let a: number

r.value = 'foo';
// ok

相关问题