Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Fix missing nuxt types #1182

Merged
merged 3 commits into from
Mar 25, 2022
Merged

Fix missing nuxt types #1182

merged 3 commits into from
Mar 25, 2022

Conversation

sarayourfriend
Copy link
Contributor

Description

In the Vue SFC typescript PR #1163 I added the types compiler option to our tsconfig and this removed some critical nuxt types from global scope. Adding them back also revealed that I'd accidentally duplicated the work that the Nuxt vue-i18n module does to make the types work so I was able to remove some code as well.

I also added an ESLint rule to prevent accidentally destructuring the i18n object as it will result in a failure if you do and try to call one of the methods destructured due to the dependency on this in the method.

Testing Instructions

Go to use-i18n.ts and call the function, make sure it has the correct types when you inspect the type information in your editor (try to use some of the properties like .t for example). This tests the removal of the code in the nuxt__types/index.d.ts module and also tests that the types from the module are being added.

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main) or a parent feature branch.
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • [N/A] I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@sarayourfriend sarayourfriend added 🟧 priority: high Stalls work on the project or its dependents 🛠 goal: fix Bug fix 🤖 aspect: dx Concerns developers' experience with the codebase ⌨️ tech: typescript Requires familiarity with TypeScript labels Mar 24, 2022
@sarayourfriend sarayourfriend requested a review from a team as a code owner March 24, 2022 16:39
@sarayourfriend sarayourfriend force-pushed the fix/missing-nuxt-types branch from f8a8e3b to 3710d31 Compare March 24, 2022 16:41
Comment on lines +36 to +38
function checkHref(p: typeof props): p is { href: string } {
return typeof p.href === 'string' && !['', '#'].includes(p.href)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks curious to me 😯 Is p is { href: string } the returning type or an extension of the params type?

Copy link
Contributor Author

@sarayourfriend sarayourfriend Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a type assertion: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions

Basically TypeScript will see this and know that any code that comes after a call to this function that uses it as a condition, that the passed in valid is { href: string } (notably here without the ? on the property making it optional).

// Out here `props.href` is `undefined | string` because `href` is an optional prop

if (checkHref(props)) {
  // in here `props.href` is no long optional, it's "proven" to be an actual string and not undefined by `checkHref`
}

// out here it is optional again because we're outside the conditional

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense for the part of the code using the checkHref function but my doubt is actually with the definition highlighted here 😅

Copy link
Contributor Author

@sarayourfriend sarayourfriend Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, sorry.

The p is { href: string } is the return type yes. Any return type with the is form is taken to be a predicate and the return value is interpreted as a boolean. It refines the type whatever the caller passes for p at the call site.

With this definition the only part we can encode in the return type is the typeof p.href === 'string' (essentially all that is being said in the return predicate). We could add the second check against the empty string and '#' but TypeScript just throws it away when you actually reference href after the check: https://www.typescriptlang.org/play?#code/C4TwDgpgBACgTgezAZygXigbygCzhAMwH4AuKZYOASwDsBzKAXwChmCBXGgY2CoRqhccELgGsAEvgIAKMGXhJkASjJgoVVNjyEyAUQAeXADbsAJhAA8FavQA0UAOQOoAH0cBiBwD4mWZlCh8YHY4ATAAOm0CdDQMB2taOmcAMmSoAEIAbSd7B08AXXDaYzMIZFlIqSVmFmYufgooMEQUdCxaqmjpIREJKVkW5SU-AObFAG5-KAB6aagAPSIpzqgBxUrCGLiHYcwpgIDZg4DFqZYWIA

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the explanation!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I see! Thank you for this explanation, the example in the link made it crystal clear. The way Typescript works is interesting.

Copy link
Member

@dhruvkb dhruvkb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great.

@sarayourfriend sarayourfriend force-pushed the fix/missing-nuxt-types branch from 3710d31 to ddf02e0 Compare March 25, 2022 10:45
@sarayourfriend sarayourfriend enabled auto-merge (squash) March 25, 2022 12:08
Copy link
Contributor

@obulat obulat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested using the instructions, works as you describe. LGTM!

Comment on lines +36 to +38
function checkHref(p: typeof props): p is { href: string } {
return typeof p.href === 'string' && !['', '#'].includes(p.href)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the explanation!

@sarayourfriend sarayourfriend merged commit f369f30 into main Mar 25, 2022
@sarayourfriend sarayourfriend deleted the fix/missing-nuxt-types branch March 25, 2022 14:16
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🤖 aspect: dx Concerns developers' experience with the codebase 🛠 goal: fix Bug fix 🟧 priority: high Stalls work on the project or its dependents ⌨️ tech: typescript Requires familiarity with TypeScript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants