最近在学习typescript的使用, 因此在学习vueuse中ts的使用,其中有个问题疑惑的问题
useTitle源码
export function useTitle(
newTitle: MaybeComputedRef<string | null | undefined> = null,
options: UseTitleOptions = {},
) {
/*
`titleTemplate` that returns the modified input string will make
the `document.title` to be different from the `title.value`,
causing the title to update infinitely if `observe` is set to `true`.
*/
const {
document = defaultDocument,
} = options
const title: WritableComputedRef<string | null | undefined> = resolveRef(newTitle ?? document?.title ?? null)
const isReadonly = newTitle && isFunction(newTitle)
function format(t: string) {
if (!('titleTemplate' in options))
return t
const template = options.titleTemplate || '%s'
return isFunction(template)
? template(t)
: unref(template).replace(/%s/g, t)
}
watch(
title,
(t, o) => {
if (t !== o && document)
document.title = format(isString(t) ? t : '')
},
{ immediate: true },
)
if ((options as any).observe && !(options as any).titleTemplate && document && !isReadonly) {
useMutationObserver(
document.head?.querySelector('title'),
() => {
if (document && document.title !== title.value)
title.value = format(document.title)
},
{ childList: true },
)
}
return title
}
其中的options
要先断言为any才能引用属性, 是否有其他办法使其更好的用到类型定义呢?
入参定义
export type UseTitleOptionsBase =
{
/**
* Observe `document.title` changes using MutationObserve
* Cannot be used together with `titleTemplate` option.
*
* @default false
*/
observe?: boolean
}
| {
/**
* The template string to parse the title (e.g., '%s | My Website')
* Cannot be used together with `observe` option.
*
* @default '%s'
*/
titleTemplate?: MaybeRef<string> | ((title: string) => string)
}
export type UseTitleOptions = ConfigurableDocument & UseTitleOptionsBase
是不是因为这里UseTitleOptionsBase
是个联合类型, 来实现observe
和titleTemplate
的互斥需求导致的?
如果不把
options
断言成any
,options.observe
和options.titleTemplate
会报错,你也可以断言成符合你要求的类型
不过这么写代码有点过于冗余了
还有一种方法是让ts自动推导,改成
这里因为他在判断之后没有取用
options.observe
的值,所以用any
最方便,虽然一般来说不太推荐断言成any
。可以参考这个demo