cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.07k stars 397 forks source link

[RFC] Move to Typescript #1035

Open HenriBeck opened 5 years ago

HenriBeck commented 5 years ago

With more OS projects now planning to move to Typescript (jest, Vue.js, etc.), I think it would be time to think about doing the same. Typescript has matured and now with eslint and babel both supporting Typescript as well, it should be future proof.

Additionally, I think the tooling around Typescript (speed, autocompletion), etc. is far head of flow currently.

I would start with "rewriting" smaller packages (like css-functions and theming) in the beginning. Also, I started writing the new docs with Typescript.

Are you willing to implement it? Yes

EDIT: I started rewriting the core in my fork in Typescript as an experiment.

TrySound commented 5 years ago

Besides better tooling I saw a lot of unsoundness in TS which is "won't fix" when flow to gonna be and actually already safer than TS in some cases. For me it doesn't worth to switch. I'm quite happy with flow in big project and open source.

HenriBeck commented 5 years ago

Why would Typescript be less type-safe?

TrySound commented 5 years ago

Here guys from flow team provides some examples https://discord.gg/zGY9gW

For example TypeScript doesn't have exact types at all (https://github.com/Microsoft/TypeScript/issues/12936) when flow is gonna have them by default. Object spread is unsound (https://github.com/Microsoft/TypeScript/issues/15454) when flow is already more sound here and is gonna improve experience with exact by default.

image

TrySound commented 5 years ago

Flow has some problems but flow team is quite active and open last few weeks. They are going to the right direction but their plan is time consuming. Now they have resources to work with community.

kof commented 5 years ago

That's interesting, do you know how many people work on flow full time? I feel like flow with strict mode and better error descriptions would actually make the whole thing quite competitive. It's just a matter if companies are willing to invest enough to improve.

TrySound commented 5 years ago

This is just now. There are more people there image

kof commented 5 years ago

Fulltime contributors? Where do you see it?

TrySound commented 5 years ago

It's a chat with flow team (facebook guys). The link I put above.

HenriBeck commented 5 years ago

I think flow error descriptions and reporting is quite better (especially when it comes to react props) than Typescripts.

What I now dislike the most about it is how slow the editor integration is and that types are an afterthought.

TrySound commented 5 years ago

Which editor do you use?

HenriBeck commented 5 years ago

Webstorm, and for me the autocompletion, auto-import etc. is really slow, I think in a recent release they improved the language server to handle request while they are recomputing all of the types though.

TrySound commented 5 years ago

There is one representative from webstrom team in flow chat. They are discussing better integration. Yeah, main problem is checking too much. Ignoring things usually helps.

HenriBeck commented 5 years ago

The reason why I proposed this change that a lot of quite large projects are moving into this direction. And yeah, TS maybe is sometimes unsafer, but I think this only applies for certain type definitions/operators.

The reason I got to like Typescript so much is that the language was designed with types in mind and not just an afterthought/addition like flow.

TrySound commented 5 years ago

Well, sorry, but herd instinct is a bad reason to refactor all the project. It looks like "flow is a shit and nobody will ever use, let's kill it". By doing this you just add fuel to the fire of hate which is really started by just one person.

By the way about big projects decisions. Here's another one https://github.com/mdn/mdn/pull/53/files#diff-992ca475abeb0c101165f19ff62d37e7R14

TrySound commented 5 years ago

And typescript was designed around the same javascript with all it's problem. It's not really different language. Reason/ocaml or haskell was designed with types.

kof commented 5 years ago

They seem to want to use flow without types or adding types gradually.

I think the goal for a library should be the highest type safety possible.

On Sat, Feb 16, 2019, 18:30 Bogdan Chadkin <notifications@github.com wrote:

Well, sorry, but herd instinct is a bad reason to refactor all the project. It looks like "flow is a shit and nobody will ever use, let's kill it". By doing this you just add fuel to the fire of hate which is really started by just one person.

By the way about big projects decisions. Here's another one

https://github.com/mdn/mdn/pull/53/files#diff-992ca475abeb0c101165f19ff62d37e7R14

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/cssinjs/jss/issues/1035#issuecomment-464365342, or mute the thread https://github.com/notifications/unsubscribe-auth/AADOWH91H4o3okJ1IrHYS1yH7RhBJXo5ks5vOEA8gaJpZM4a-V26 .

HenriBeck commented 5 years ago

I never said that Typescript is a different language and has not the problems of javascript, but at the same time Typescript was designed around types (which in my opinion solves a few of them). The best comparison for that in my mind is how you import/export types in Typescript vs. flow.

TrySound commented 5 years ago

Flow was also designed around types. It's type system.

Well, I dont see any sense in import way. It's just a choice without "not types in mind"

Flow coming types first arch name is quite descriptive.

HenriBeck commented 5 years ago

What I mean by "designed around types" is that flow tries to add types on top of javascript, and Typescript is a superset of javascript which compiles down to js.

kof commented 5 years ago

That just means that flow is not going to add language features, just types, where typescript has done so and might do more. In that sense, ts has more power. At the same time, the more ts does so, the further away it is from js.

Most things other than that are basically implementation details and features which one has but another one doesn't and vise versa.

I think we need to clearly define the criteria for our choice first of all. Knowing we are working in a library context.

TrySound commented 5 years ago

Its not true. Both add types and invalid syntax to javascript. Both are compiled to javascript. But flow team just is a bit more careful with JS semantics.

kof commented 5 years ago

Where did flow add something that compiles to runtime javascript?

TrySound commented 5 years ago

Well exact types is a good reason to stay with flow.

TrySound commented 5 years ago

What babel compiles to JS from TS?

kof commented 5 years ago

For example

enum Direction {
    Up = 1,
    Down,
    Left,
    Right,
}
kof commented 5 years ago

Well exact types is a good reason to stay with flow.

Can you expand pls? Afaik both have this, but mb you know more than I do

kof commented 5 years ago

TBH my biggest problem with both flow and TS is to maintain types for both. Ideally I want to do it only once.

TrySound commented 5 years ago

Read the thread. TS doesnt have exact types.

TrySound commented 5 years ago

AFAIK enums are not compiled via babel.

TrySound commented 5 years ago

@kof Flow team is working on definitions generator which will allows simply map them to TS typings.

HenriBeck commented 5 years ago

But TS already has it, and yeah maybe TS is sometimes a little bit less type-safe but so is flow in some cases.

So, in the end, I think it comes down to these points:

Feel free to add points to the list; I might have missed some.

kof commented 5 years ago
jeremy-coleman commented 5 years ago

https://github.com/yarnpkg/berry/tree/master/packages Yarn v2, Rxjs, vue, angular, inferno, Mobx , all ts. Typescript is a better choice. Although really , you should look at your dependants and make the choice based on that. Fyi after retyping core ive found several problems on the current types, as with most flow libraries. If you do decide to switch to typescript, i will gladly help, it wont take long

TrySound commented 5 years ago

@jeremy-coleman Retyping to flow may also catch errors. Both type systems have own features.

kof commented 5 years ago

We have ts types for public api, feel free to submit your fixes if they can improve those for now.

On Mon, Mar 4, 2019, 08:36 Jeremy <notifications@github.com wrote:

https://github.com/yarnpkg/berry/tree/master/packages Yarn v2, Rxjs, vue, angular, inferno, Mobx , all ts. Typescript is a better choice. Although really , you should look at your dependants and make the choice based on that. Fyi after retyping core ive found several problems on the current types, as with most flow libraries. If you do decide to switch to typescript, i will gladly help, it wont take long

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cssinjs/jss/issues/1035#issuecomment-469148338, or mute the thread https://github.com/notifications/unsubscribe-auth/AADOWOjvHIRwO1o7H8gPNhp5I18chsmAks5vTM0ZgaJpZM4a-V26 .

jeremy-coleman commented 5 years ago

I mostly changed source code in core only and integrated with glamor jss. , i dont think its usable outside my use case. Honestly though, csstype and the built in dom types have already done most the work, for me its easier to start from a js base than flow and focus on adding types to the input params (which is super easy if you already understand how the code works ) . There are also some codemods for flow to ts , havnt tried them out though. Jss is in a tough spot though bc of the plugin system. It would probably be better to create a second repo for the ts version like jss-ts or something

HenriBeck commented 5 years ago

Creating a separate version just for TS isn't an option as we would need to do bug fixes etc. twice.

kof commented 5 years ago

@jeremy-coleman you mean create a repo with a specific plugins setup that imports from main repo and exposes types or did you suggest to copy the entire codebase?

worudso commented 5 years ago

@kof @jeremy-coleman https://github.com/cssinjs/jss/issues/1036 As I mentioned in the last comment in that issue, I suggest making createStyleSheet generic to support typings for plugins, providing typings for vanilla jss as default.

// it only allows vanilla jss's style definition
jss.createStyleSheet({
  // ...
})

import { NestedStyle } from "jss-plugin-nested"; // it's not there now.
import { ObservableStyle } from "jss-plugin-rule-value-observable";
jss.createStyleSheet<NestedStyle & ObservableStyle>({
  // ...
})

The current type definition under devleopment partially supports plugins listed on https://cssinjs.org/. It supports jss-plugin-rule-value-observable but doesn't support jss-plugin-nested. And what about 3rd-party plugins? Is it ok that they are left untyped and force programmers to type any?

jeremy-coleman commented 5 years ago

https://github.com/jeremy-coleman/jss

HenriBeck commented 5 years ago

I think both type systems have their features and flaws. Both of them are not perfect, but I believe Typescript would give us a better DX than flow.

Also, I just noticed that in flow you couldn't extend interfaces which I find a little bit weird.

TrySound commented 5 years ago

I feel object type spread with exact types is more natural than extending interfaces.

oliviertassinari commented 5 years ago

You cannot prove any interesting properties about TypeScript code without soundness, so why did the designers intentionally break soundness?

TypeScript challenges the status quo, claiming that lowering the cognitive overhead of using types is more important than type soundness. They argue that JavaScript programmers, their main audience, would find it easier to use TypeScript if they deviated from traditional norms.

Pragmatism? https://frenchy64.github.io/2018/04/07/unsoundness-in-untyped-types.html

HenriBeck commented 5 years ago

I just tried upgrading to a newer flow version, and we had problems with our memoize function, so I tried to fix it that it's still type-safe and at the same time generic. I couldn't find a solution, because there is no way of defining overload types for functions.

HenriBeck commented 5 years ago

Also, I wasn't able to get [declarations] in the config working to ignore a new error inside the node_modules

HenriBeck commented 5 years ago

I would prefer it if we did an incremental switch to typescript. I think the developer experience is far inferior to Flow and we might even see more engagement from the community in terms of PRs.

rob2d commented 5 years ago

$.02: you can use Typescript in ESDoc with VSCode (and now probably other decent IDEs going forward) and get all of the annotations/auto predictions/linting without wasting time you could be using on more productive things... Like developing features and making sure there's good integration tests (followed by unit tests if life is luxurious, but good developers think in unit tests while they code as habit).

jeremy-coleman commented 5 years ago

@HenriBeck i think you meant the dev experience is far superior? :P

Saturate commented 5 years ago

I would prefer it if we did an incremental switch to typescript. I think the developer experience is far inferior to Flow and we might even see more engagement from the community in terms of PRs.

I would like to contribute to this change. Is there any plan going forward?

I'm thinking if we can add the babel typescript plugin, it should be possible to do it incremental and rewrite modules pretty easily.

kof commented 5 years ago

Another option I discovered today, also used by preact https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html

Checking types using jsdoc types using ts compiler.