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

[styled-components] Move React Native-dependent types to separate package #49914

Merged
merged 1 commit into from Dec 18, 2020

Conversation

Methuselah96
Copy link
Contributor

@Methuselah96 Methuselah96 commented Dec 3, 2020

Resolves #33311
Resolves #33015

The problem

Both of the above issues have been open for over a year and a half and the first one has more up-votes than any other issue on DefinitelyTyped. The current solution on these issues is to set the types: [] in tsconfig.json to pull in the appropriate types, which means @types/styled-components doesn't work out-of-the-box unlike most other @types packages. This harms not only the reputation of TypeScript, but also the reputation of styled-components and causes unnecessary friction in order to use these types.

The solution

Move the styled-components/native types out of @types/styled-components and into its own package (@types/styled-components-react-native). If someone wants to use styled-components/native, all they need to do is install @types/styled-components-react-native and it will automatically augment the styled-components types (since TypeScript automatically includes any installed @types packages).

This makes it so that the main export (i.e., import styled from 'styled-components') works out-of-the-box (which is the most common usage). And in order to get styled-components/native all you need to do is install the other @types package, which is still easier than having to set types: [] in tsconfig.json.

Note: this is still just a temporary workaround, but it is still better than the current situation.


Please fill in this template.

If adding a new definition:

  • The package does not already provide its own types, or cannot have its .d.ts files generated via --declaration
  • If this is for an NPM package, match the name. If not, do not conflict with the name of an NPM package.
  • Create it with dts-gen --dt, not by basing it on an existing project.
  • Represents shape of module/library correctly
  • tslint.json should be present and it shouldn't have any additional or disabling of rules. Just content as { "extends": "dtslint/dt.json" }. If for reason the some rule need to be disabled, disable it for that line using // tslint:disable-next-line [ruleName] and not for whole package so that the need for disabling can be reviewed.
  • tsconfig.json should have noImplicitAny, noImplicitThis, strictNullChecks, and strictFunctionTypes set to true.

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: N/A
  • If this PR brings the type definitions up to date with a new version of the JS library, update the version number in the header.
  • If you are making substantial changes, consider adding a tslint.json containing { "extends": "dtslint/dt.json" }. If for reason the any rule need to be disabled, disable it for that line using // tslint:disable-next-line [ruleName] and not for whole package so that the need for disabling can be reviewed.

@typescript-bot typescript-bot added New Definition This PR creates a new definition package. Popular package This PR affects a popular package (as counted by NPM download counts). Edits multiple packages labels Dec 3, 2020
@typescript-bot typescript-bot added this to Waiting for Code Reviews in New Pull Request Status Board Dec 3, 2020
@typescript-bot
Copy link
Contributor

typescript-bot commented Dec 3, 2020

@Methuselah96 Thank you for submitting this PR!

This is a live comment which I will keep updated.

2 packages in this PR

Code Reviews

This PR adds a new definition, so it needs to be reviewed by a DT maintainer before it can be merged.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • ❌ Only a DT maintainer can approve changes when there are new packages added

Once every item on this list is checked, I'll ask you for permission to merge and publish the changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 49914,
  "author": "Methuselah96",
  "headCommitAbbrOid": "48542fd",
  "headCommitOid": "48542fd96a519ae9ae79d1c1dd70c771a6f13e83",
  "lastPushDate": "2020-12-18T16:04:32.000Z",
  "lastActivityDate": "2020-12-18T16:42:46.000Z",
  "maintainerBlessed": false,
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "popularityLevel": "Popular",
  "pkgInfo": [
    {
      "name": "styled-components-react-native",
      "kind": "add",
      "files": [
        {
          "path": "types/styled-components-react-native/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/styled-components-react-native/styled-components-react-native-tests.tsx",
          "kind": "test"
        },
        {
          "path": "types/styled-components-react-native/tsconfig.json",
          "kind": "package-meta",
          "suspect": "not [the required form](https://github.com/DefinitelyTyped/DefinitelyTyped#tsconfigjson)"
        },
        {
          "path": "types/styled-components-react-native/tslint.json",
          "kind": "package-meta",
          "suspect": "not [the required form](https://github.com/DefinitelyTyped/DefinitelyTyped#linter-tslintjson)"
        }
      ],
      "owners": [],
      "addedOwners": [
        "Methuselah96"
      ],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "styled-components",
      "kind": "edit",
      "files": [
        {
          "path": "types/styled-components/native.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/styled-components/ts3.6/native.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/styled-components/ts3.6/test/native.tsx",
          "kind": "test"
        },
        {
          "path": "types/styled-components/ts3.6/tsconfig.json",
          "kind": "package-meta",
          "suspect": "not [the required form](https://github.com/DefinitelyTyped/DefinitelyTyped#tsconfigjson) and not moving towards it"
        },
        {
          "path": "types/styled-components/tsconfig.json",
          "kind": "package-meta",
          "suspect": "not [the required form](https://github.com/DefinitelyTyped/DefinitelyTyped#tsconfigjson) and not moving towards it"
        }
      ],
      "owners": [
        "Igorbek",
        "Igmat",
        "lavoaster",
        "Jessidhia",
        "jkillian",
        "eps1lon",
        "flavordaaave",
        "wagerfield",
        "Lazyuki",
        "mgoszcz2",
        "danilofuchs"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Popular"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "eps1lon",
      "date": "2020-12-18T16:42:46.000Z",
      "isMaintainer": false
    },
    {
      "type": "stale",
      "reviewer": "alloy",
      "date": "2020-12-16T12:12:35.000Z",
      "abbrOid": "aa7deb3"
    },
    {
      "type": "stale",
      "reviewer": "paulmelnikow",
      "date": "2020-12-15T17:39:32.000Z",
      "abbrOid": "aa7deb3"
    }
  ],
  "ciResult": "pass"
}

@typescript-bot
Copy link
Contributor

🔔 @Igorbek @Igmat @lavoaster @Jessidhia @jkillian @eps1lon @flavordaaave @wagerfield @Lazyuki @mgoszcz2 @danilofuchs — please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

@typescript-bot typescript-bot added the The CI failed When GH Actions fails label Dec 3, 2020
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Author Action in New Pull Request Status Board Dec 3, 2020
@typescript-bot
Copy link
Contributor

@Methuselah96 The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot
Copy link
Contributor

@Methuselah96 The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot
Copy link
Contributor

👋 Hi there! I’ve run some quick measurements against master and your PR. These metrics should help the humans reviewing this PR gauge whether it might negatively affect compile times or editor responsiveness for users who install these typings.

Let’s review the numbers, shall we?

styled-components-react-native/v5.1

These typings are for a package that doesn’t yet exist on master, so I don’t have anything to compare against yet! In the future, I’ll be able to compare PRs to styled-components-react-native with its source on master.

Comparison details for styled-components-react-native/5.1 📊
Batch compilation
Type count 65647
Assignability cache size 19622
Language service measurements
Samples taken 200
Identifiers in tests 200
getCompletionsAtPosition
    Mean duration (ms) 545.9
    Mean CV 9.3%
    Worst duration (ms) 985.8
    Worst identifier ThemedView2
getQuickInfoAtPosition
    Mean duration (ms) 580.6
    Mean CV 9.3%
    Worst duration (ms) 868.8
    Worst identifier themedExports
System information
Node version v14.15.0
CPU count 2
CPU speed 2.294 GHz
CPU model Intel(R) Xeon(R) CPU E5-2673 v4 @ 2.30GHz
CPU Architecture x64
Memory 6.8 GiB
Platform linux
Release 4.15.0-1098-azure

styled-components/v5.1

master #49914 diff
Batch compilation
Memory usage (MiB) 195.6 216.6 +10.7%
Type count 104538 91839 -12%
Assignability cache size 33626 30698 -9%
Language service
Samples taken 1207 1207 0%
Identifiers in tests 1414 1214 -14%
getCompletionsAtPosition
    Mean duration (ms) 631.9 826.5 +30.8% 🔸
    Mean CV 8.8% 7.9%
    Worst duration (ms) 3060.7 2908.0 -5.0%
    Worst identifier p color
getQuickInfoAtPosition
    Mean duration (ms) 648.5 840.5 +29.6% 🔸
    Mean CV 9.1% 8.4%
    Worst duration (ms) 2814.3 2730.1 -3.0%
    Worst identifier WithProp WithComponentFirstStyledB

Looks like there were a couple significant differences—take a look at mean duration for getting completions at a position and mean duration for getting quick info at a position to make sure everything looks ok.

@typescript-bot typescript-bot added the Perf: Worse typescript-bot determined that this PR has a negative impact on compilation performance. label Dec 3, 2020
@Methuselah96
Copy link
Contributor Author

Methuselah96 commented Dec 3, 2020

Build failing due to microsoft/TypeScript#41790, but should be good besides that.

@danger-public
Copy link

danger-public commented Dec 4, 2020

Inspecting the JavaScript source for this package found some properties that are not in the .d.ts files.
The check for missing properties isn't always right, so take this list as advice, not a requirement.

styled-components (unpkg)

was missing the following properties:

  1. StyleSheetConsumer
  2. StyleSheetContext
  3. version

Generated by 🚫 dangerJS against 48542fd

@typescript-bot typescript-bot removed the The CI failed When GH Actions fails label Dec 4, 2020
@typescript-bot typescript-bot moved this from Needs Author Action to Needs Maintainer Action in New Pull Request Status Board Dec 4, 2020
@typescript-bot
Copy link
Contributor

Updated numbers for you here from eb300d1.

styled-components-react-native/v5.1

These typings are for a package that doesn’t yet exist on master, so I don’t have anything to compare against yet! In the future, I’ll be able to compare PRs to styled-components-react-native with its source on master.

Comparison details for styled-components-react-native/5.1 📊
Batch compilation
Type count 57272
Assignability cache size 18605
Language service measurements
Samples taken 200
Identifiers in tests 200
getCompletionsAtPosition
    Mean duration (ms) 481.8
    Mean CV 9.0%
    Worst duration (ms) 934.0
    Worst identifier StyledText
getQuickInfoAtPosition
    Mean duration (ms) 509.8
    Mean CV 9.5%
    Worst duration (ms) 783.9
    Worst identifier themedExports
System information
Node version v14.15.1
CPU count 2
CPU speed 2.095 GHz
CPU model Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz
CPU Architecture x64
Memory 6.8 GiB
Platform linux
Release 4.15.0-1098-azure

styled-components/v5.1

Comparison details for styled-components/5.1 📊
master #49914 diff
Batch compilation
Memory usage (MiB) 187.3 199.8 +6.7%
Type count 85920 77247 -10%
Assignability cache size 32317 29847 -8%
Language service
Samples taken 1231 1207 -2%
Identifiers in tests 1414 1214 -14%
getCompletionsAtPosition
    Mean duration (ms) 581.8 748.9 +28.7% 🔸
    Mean CV 8.3% 8.0%
    Worst duration (ms) 2784.2 2523.0 -9.4%
    Worst identifier invalidProp color
getQuickInfoAtPosition
    Mean duration (ms) 597.5 763.1 +27.7% 🔸
    Mean CV 8.6% 8.3%
    Worst duration (ms) 2689.1 2330.6 -13.3%
    Worst identifier WithProp attrs

Looks like there were a couple significant differences—take a look at mean duration for getting completions at a position and mean duration for getting quick info at a position to make sure everything looks ok.

@orta
Copy link
Collaborator

orta commented Dec 15, 2020

👋 - I've done my digging. TLDR: I think we should merge this.

I have a sample repo with before and after examples for both node and react native projects here with the README being a summary of how they act out of the box.

What this PR proposes is that we remove the native.d.ts file from @types/styled-components, and move that into a new types module. This types module edits the global scope to declare that it has a definition for "styled-components/native" specifically, which adds the react-native types to the module.

Upsides

  • Web works out of the box again. Currently only React Native projects get that.
  • Does not need to wait for the TS team to figure out an answer for per-file environments (which is looking to be very hard)
  • SC React Native types could be maintained by a different set of folks, doesn't really seem too valuable in comparison to the above points though.

Downsides

  • React Native projects need to yarn add @types/styled-components-react-native to get types
  • React Native projects using JS do not get ATA anymore

A React Native project which does not have @types/styled-components-react-native installed gets this:

styled-components-types-tests/proposed_rn on  main [✘!?] is 📦 v1.0.0 via ⬢ v14.15.1 
❯ yarn compile
yarn run v1.22.10
$ ../node_modules/.bin/tsc --noEmit
index.tsx:3:20 - error TS7016: Could not find a declaration file for module 'styled-components/native'. '/home/orta/dev/typescript/styled-components-types-tests/proposed_rn/node_modules/styled-components/native/dist/styled-components.native.cjs.js' implicitly has an 'any' type.

Trade-offs

Given the size differences in the amount of developers working on the web vs react native, I think having SC broken for the web in favour of RN support being 1st class isn't a great trade-off. There's a lot of creative answers to the issue, but I think this is the best option we have right now. With the cost being that people need to learn to get the new dependency for React Native, which I think is pretty reasonable.

IMO, I think these trade-offs can be mitigated by improving the Styled Components docs in the TypeScript section.

The docs can mention TS + RN specifically as needing this extra dep, and I think that should be reasonably harmless. Ideally a FAQ entry can be added around this error message: Could not find a declaration file for module 'styled-components/native' - which is just "install this dep" too ( /cc @probablyup does that seem reasonable? )

I'm going to go ping a few threads asking for feedback on this PR as a solid potential solution. Then once more folks have given input we can make a call on whether to merge or not 👍🏻 - thanks for getting the ball rolling @Methuselah96


<edit>
It also looks like the RN support will be getting split out in the next major version of Styled Components which I think makes this more temporary also.
</edit>

@typescript-bot typescript-bot added the Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. label Dec 15, 2020
@typescript-bot
Copy link
Contributor

Re-ping @Igorbek, @Igmat, @lavoaster, @Jessidhia, @jkillian, @eps1lon, @flavordaaave, @wagerfield, @Lazyuki, @mgoszcz2, @danilofuchs:

This PR has been out for over a week, yet I haven't seen any reviews.

Could someone please give it some attention? Thanks!

@murbanowicz
Copy link
Contributor

This is more than needed.
It often requires workarounds to mitigate issues caused by the fact that Native parts are installed with web stuff.

Copy link
Collaborator

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

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

#49914 (comment) summarizes this perfectly. @orta Thanks looking into the impact this change has 👍

@typescript-bot typescript-bot added the Owner Approved A listed owner of this package signed off on the pull request. label Dec 15, 2020
@jussikinnula
Copy link
Contributor

This all looks good.

Just a question. Could we somehow include an error, if someone uses @types/styled-components in React Native project?

Basically there's global.navigator.product which returns ReactNative which could be used for this. I think it would ease up people upgrading to use @types/styled-components-react-native if they would get instructions sooner than to have to dig the information.

@typescript-bot
Copy link
Contributor

Updated numbers for you here from 86733a3.

styled-components-react-native/v5.1

These typings are for a package that doesn’t yet exist on master, so I don’t have anything to compare against yet! In the future, I’ll be able to compare PRs to styled-components-react-native with its source on master.

Comparison details for styled-components-react-native/5.1 📊
Batch compilation
Type count 67654
Assignability cache size 16719
Language service measurements
Samples taken 200
Identifiers in tests 200
getCompletionsAtPosition
    Mean duration (ms) 508.1
    Mean CV 9.1%
    Worst duration (ms) 940.5
    Worst identifier randoName
getQuickInfoAtPosition
    Mean duration (ms) 538.3
    Mean CV 9.5%
    Worst duration (ms) 768.9
    Worst identifier themedCssWithNesting
System information
Node version v14.15.1
CPU count 2
CPU speed 2.095 GHz
CPU model Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz
CPU Architecture x64
Memory 6.8 GiB
Platform linux
Release 4.15.0-1100-azure

styled-components/v5.1

Comparison details for styled-components/5.1 📊
master #49914 diff
Batch compilation
Memory usage (MiB) 195.9 216.4 +10.4%
Type count 83578 77736 -7%
Assignability cache size 24482 23390 -4%
Language service
Samples taken 1239 1239 0%
Identifiers in tests 1446 1246 -14%
getCompletionsAtPosition
    Mean duration (ms) 643.4 828.4 +28.7% 🔸
    Mean CV 7.8% 7.3%
    Worst duration (ms) 4224.0 3325.3 -21.3%
    Worst identifier invalidProp forwardedAs
getQuickInfoAtPosition
    Mean duration (ms) 658.0 842.2 +28.0% 🔸
    Mean CV 8.3% 7.5%
    Worst duration (ms) 3399.5 3172.6 -6.7%
    Worst identifier WithProp WithProp

Looks like there were a couple significant differences—take a look at mean duration for getting completions at a position and mean duration for getting quick info at a position to make sure everything looks ok.

@orta
Copy link
Collaborator

orta commented Dec 18, 2020

Alright, we are good to go - thanks for the rebase @Methuselah96 !

@orta orta merged commit 0cdacee into DefinitelyTyped:master Dec 18, 2020
@Methuselah96 Methuselah96 deleted the styled-components-native branch December 18, 2020 18:34
@typescript-bot
Copy link
Contributor

I just published @types/styled-components@5.1.7 to npm.

@typescript-bot
Copy link
Contributor

I just published @types/styled-components-react-native@5.1.0 to npm.

@lukewlms
Copy link

I'm probably missing something simple but how do you actually use this? I've tried a bunch of variations on installing the new Native types lib, the old one, only one of them, both of them, setting a path in tsconfig...

If I just install both of them then when I try to import styled-components/native I get:

Could not find a declaration file for module 'styled-components/native'. 'node_modules/styled-components/native/dist/styled-components.native.cjs.js' implicitly has an 'any' type.ts(7016)

I'm just trying to make a Styled.ScrollView work, which worked before trying to migrate to the new types.

@lukewlms
Copy link

lukewlms commented Feb 15, 2021

Ok, here's what seems to be working:

  1. yarn add --dev @types/styled-components @types/styled-components-react-native
  2. Add explicit paths in tsconfig to the new types (the first accesses the types, the second prevents errors with other packages referencing this lib's packaged, older react-native types:
    "baseUrl": ".",
    "paths": {
      "styled-components/native": [
        "node_modules/@types/styled-components-react-native"
      ],
      "react-native": ["node_modules/@types/react-native"]
    },

If this is the intended way it seems it would be worthwhile to document in the npm readme.

@Methuselah96
Copy link
Contributor Author

Is it possible that you have the types property specified in your tsconfig.json? It should work automatically if you don't specify the types field. If you are specifying it, you should add styled-components-react-native to that array.

@lukewlms
Copy link

@Methuselah96 Thanks for the help - yes, we specify types for Jest. If I add styled-components-react-native there, then it looks like I can remove it from Paths so either way to set up config works, but some special config is needed either way.

Seems worth putting in readme.md to me since I haven't run into this in other libs in a fair amount of experience, + using paths is common as far as I know (e.g. for Jest as we do).

@Methuselah96
Copy link
Contributor Author

Methuselah96 commented Feb 16, 2021

Apologies for the confusion. It would be great if you could make a PR to add documentation for this case to the TypeScript section on the styled-components website. I think it's more common than not that people aren't specifying the types property in tsconfig.json, but I have no data to back that claim up.

lukewlms added a commit to lukewlms/styled-components-website that referenced this pull request Feb 16, 2021
If this isn't done then the types won't be found, if `types` is already set.  Per author @Methuselah96: DefinitelyTyped/DefinitelyTyped#49914 (comment)
lukewlms added a commit to lukewlms/styled-components-website that referenced this pull request Feb 16, 2021
If this isn't done then the types won't be found, if `types` is already set.  Per author @Methuselah96: DefinitelyTyped/DefinitelyTyped#49914 (comment)
lukewlms added a commit to lukewlms/styled-components-website that referenced this pull request Feb 16, 2021
If this isn't done then the types won't be found, if `types` is already set.  Per author @Methuselah96: DefinitelyTyped/DefinitelyTyped#49914 (comment)
@lukewlms
Copy link

Apologies for the confusion. It would be great if you could make a PR to add documentation for this case to the TypeScript section on the styled-components website. I think it's more common than not that people aren't specifying the types property in tsconfig.json, but I have no data to back that claim up.

No problem, thanks again for the help and I submitted a PR.

@ortonomy
Copy link

Thank you so much @lukewlms and @Methuselah96 -- without finding this issue, I would never have solved the problem of the types not being found.

@davisk4rpi
Copy link
Contributor

It seems like @types/styled-components to 5.1.7 has broken this fix.

I have @types/styled-components-react-native installed as well and I cant seem to find any workarounds to get this to work other than setting "noImplicitAny" to false

@ortonomy
Copy link

@davisk4rpi - make sure you're not using any other definitions in 'typeSrc' or 'types' - if you are, it breaks.

@Methuselah96
Copy link
Contributor Author

Just to clarify, you're allowed to have other definitions in "types", just make sure that "styled-components-react-native" is one of them as shown in the docs.

@ortonomy
Copy link

Yes. Sorry. I should have said if it's a not empty array you should added the types to the array.

@davisk4rpi
Copy link
Contributor

@ortonomy @Methuselah96 Thanks, That was it. didnt notice the types field in my config the first time through

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Check Config Changes a module config files Edits multiple packages New Definition This PR creates a new definition package. Owner Approved A listed owner of this package signed off on the pull request. Perf: Worse typescript-bot determined that this PR has a negative impact on compilation performance. Popular package This PR affects a popular package (as counted by NPM download counts).
Projects
None yet