Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types(shared): Improve LooseRequired<T> #6244

Merged
merged 3 commits into from
Oct 26, 2022

Conversation

browsnet
Copy link
Contributor

@browsnet browsnet commented Jul 9, 2022

Improve the implementation of LooseRequired<T>.

The purpose of LooseRequired<T> is to change the Optional Properties in an Object Type to required, while keeping the undefined type.

In the current version, LooseRequire is implemented as follows.

type LooseRequired<T> = { [P in string & keyof T]: T[P] }

This implementation has problems when it encounters index signatures, consider the following code.

type Result = LooseRequired<{
  [x:string]:any
  a?:1
  b:false
}>

The result here is { [x: string]: any; }

This is because when the object type contains a string index signature, the keyof T will return string, so all other properties cannot be mapped

But TypeScript keyof T is a lazy value in the case of [P in keyof T], so we can guarantee that every property can be mapped as long as we don't expand it by using keof T.

To achieve the purpose of LooseRequired<T>, we can first set all the properties of T to required and then map the corresponding types.

Here is the improved LooseRequired<T>:

type LooseRequired<T> = { [P in keyof (T & Required<T>)]: T[P] }

We can do a few tests

type Test1 = LooseRequired<{
    [x: string]: any;
    a?: 1;
    b: false;
}>

The result is :

{
    [x: string]: any;
    a: 1 | undefined;
    b: false;
}

Another example is

type Test2 = LooseRequired< {
    [x: `on${string}`]: Function;
    onHandle: () => number;
}>

The result is

{
    [x: `on${string}`]: Function;
    onHandle: () => number;
}

You can see that it avoids the attribute value merging problem caused by the keyof T being computed.

Improve the implementation of `LooseRequired<T>`.
@netlify
Copy link

netlify bot commented Jul 9, 2022

Deploy Preview for vue-sfc-playground failed.

Name Link
🔨 Latest commit 489df2e
🔍 Latest deploy log https://app.netlify.com/sites/vue-sfc-playground/deploys/62c97ce44c877a000886e055

@netlify
Copy link

netlify bot commented Jul 9, 2022

Deploy Preview for vuejs-coverage failed.

Name Link
🔨 Latest commit 489df2e
🔍 Latest deploy log https://app.netlify.com/sites/vuejs-coverage/deploys/62c97ce49ec006000a0889b5

Improve the implementation of LooseRequired<T>.
packages/shared/src/typeUtils.ts Outdated Show resolved Hide resolved
@yyx990803 yyx990803 merged commit cbc3e67 into vuejs:main Oct 26, 2022
chrislone pushed a commit to chrislone/core that referenced this pull request Feb 4, 2023
zhangzhonghe pushed a commit to zhangzhonghe/core that referenced this pull request Apr 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants