Description
Vue version
3.5.6
Link to minimal reproduction
Steps to reproduce
Mouse over msg1
, msg2
, msg3
to see the type hints for each constant: you will see inner type several times instead of one, as before #11442 was merged.
What is expected?
Mouse over msg4
, msg5
, msg6
to see the type hints for each constant: you will see inner type just once, as it was before changes introduced in #11442.
What is actually happening?
After the changes introduced in #11442 the Ref
type has 2 type arguments (for a long period of time it was just one). Type hints for both of them are shown on mouse over.
They are usually the same, but still shown 2 times. This makes it much more harder to read the inferred type. Before the changes introduced in #11442 reading the types of Ref
s was much more convenient and I think it is important enough as ref
is one of the core building blocks of every Vue application and reading complex Typescript types is hard enough already.
System Info
Vue Playground
Any additional comments?
In #11442 a new 2nd type parameter S
was introduced to the Ref
type.
This change makes type hints (like in VSCode) hard to read as the inferred type parameter is always duplicated.
Example:
const msg = ref('Hello World!')
Previously (during many years) when you mouse over on the msg
in VSCode, you were seen this:
const msg: Ref<string>
Now you see this:
const msg: Ref<string, string>
This is not big deal when the type is simple like string
, but when it is complex and multi-line, this duplication makes type reading much harder than it was before the change of the Ref
type.
Is it possible to make the second type to be hidden in type hints when it is identical to the first type? Formally it is not identical as T
will be UnwrapRef<T>
, while S
will be UnwrapRef<T> | T
, but maybe there is a way to do it?
I'm not that good in TypeScript types, so can't suggest any solution, but I tried to just create an intermediate type like this:
type RefFixed<T> = Ref<UnwrapRef<T>, UnwrapRef<T> | T>
// An original `ref` declaration that is currently in Vue:
// export declare function ref<T>(value: T): [T] extends [Ref] ? IfAny<T, Ref<T>, T> : Ref<UnwrapRef<T>, UnwrapRef<T> | T>;
// A "fixed" declaration:
function ref2<T>(value: T): [T] extends [Ref] ? IfAny<T, Ref<T>, T> : RefFixed<T> {
return ref(value)
}
(see the playground example above)
I.e. RefFixed<T>
is used instead of Ref<UnwrapRef<T>, UnwrapRef<T> | T>
in the return type of ref
.
And looks like it helps with type hints.
So, maybe this or some more sophisticated solution could be implemented?