Skip to content

Improve type hints that were worsened by adding a second type argument to the Ref type #11969

Open
@xak2000

Description

@xak2000

Vue version

3.5.6

Link to minimal reproduction

https://play.vuejs.org/#eNqlVNtu2kAQ/ZWpX5xIxCjcHqhDm1apmkq9KKXqQxxVxh7jTda71u4aiCj/3tk1AUMCrVQ/WPbOmTO3s7P0LssymFXoDb1QJ4qVBjSaqgQei+lF5BkdeaNIsKKUyoB5LBGWcJ1dikdYQaZkAf5bcm/rPFaY+q/3oTeYteCHmKu4pM+ND7n4G+gS1DNTJNpt8kukmKFgKNaEOaMvXMRFyVEPoZCVRpAzVFDo6XnLvjvu3YUzx+q8mIa0KjlLYoNpy1HPc5bkUMQPqAkXp0xMweRY44vK2qSieLFKMSVLLIAZmMcaJpiRJYhsbtq4uHBhY534H5FzCT+l4ukr/7SB6KwRS5gMYRcGqyaw2wS+wOnQroDP29L9WcypaVQxpUi1ZkxQDVIb/rhOU3IMuJye2GQDh14HbRg6hwzdjcEFPls/cCkgNgYLkoyRFHSxHZHeoOxjHZ2JFPCBLTANxyOqk/7CjTLoqKETC/gNYxJeVonEMClsMzp0fOJyGcL4dAi34zvSgkGRarglrzt4U0szHLccu+UkpuFO4GUkgNhMpRxpTUjFrZ43lorvOTX13Xuwp6kJUvmqBZPKzW4A2jDOSTMaKldJSdLxJ75zaAy5Vw+5c0Qw/SfIXxUz2EEelszeUHuHpt0/ZBg0ZBC2611BA6IfqwFOV4v+AML8fNRoYZjIFEf7lzNsu2OrmyTH5GF79Zx6grBNLMfYdsbyf2x1Wf/IEbYbxXotWo/UpYxNg3stBe1QJ67IS2RRMo7qa2m1Syt0WMvO2mIazvyTOzOqQlpH9bkL+8L5vV7Ys8j7plCjmmHkbWwmVlM0tfnq+xe6DA1jIdOKE/qI8QZpwpXNsYa9q0RKaTdwLttrt6dpRY71lb1v+qkom6hFrhw+8mh3vz9S+jbdbtBzfnTtqIu/aBqWkxrYDfrBwFv9ATlTNQE=

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 Refs 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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions