Skip to content

Static typing with typescript #10

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

Merged
merged 8 commits into from
Mar 21, 2016
Merged

Static typing with typescript #10

merged 8 commits into from
Mar 21, 2016

Conversation

jbaxleyiii
Copy link
Contributor

This PR is alternative way to solve #6 using typescript instead of flow.

Pros:

  • typescript seems to be a more robust typings solution. Things that flow allowed, typescript has flagged. (Although my flow setup is probably not 100%)
  • typescript auto generates type definitions for source methods. This makes exporting types trivial. (Again, this could be possible in flow but from what I saw, you have to manually define export types in flow)
  • singular build + typechecking
  • more robust editor integration

Cons:

  • no support for ES7/8 spread operators let foo = { ...bar }

@jbaxleyiii jbaxleyiii mentioned this pull request Mar 21, 2016
@stubailo
Copy link
Contributor

Actually I feel like both things listed as drawbacks for typescript here are actually issues with my code!

  1. My argument serialization for the cache key is not complete, and just doesn't handle list values properly, among other things
  2. I think it isn't a good idea to change the type of a value mid-function so I think it would be best to change that code!

@jbaxleyiii jbaxleyiii mentioned this pull request Mar 21, 2016
@jbaxleyiii
Copy link
Contributor Author

@stubailo I've made a branch to verify the CI will handle typescript correctly and highlight the current issues. If we want to slowly adopt typescript, we can use any in places where we still aren't strict enough with types?

here is the branch https://github.com/apollostack/apollo-client/tree/typescript-weak

@@ -0,0 +1,60 @@
/// <reference path="../typings/browser/ambient/es6-promise/index.d.ts" />
/// <reference path="../typings/browser/ambient/graphql/index.d.ts" />
/// <reference path="../typings/browser/definitions/lodash/index.d.ts" />

Choose a reason for hiding this comment

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

I think you can avoid these <reference path /> on top of every file by including the /typings directory to the list of typescript files in tsconfig.json.

@mquandalle
Copy link

On object spread, I agree that it’s a bit unfortunate that Typescript doesn’t support it given how popular they are in the Redux/functionalJS communities. Hopefully it will come sooner than latter, microsoft/TypeScript#2103, and so using Object.assign for now and replacing them by object spread when it arrives is reasonable.

@stubailo
Copy link
Contributor

Hmm, that's kind of a bummer - it's a reminder that TypeScript isn't compatible with all future JavaScript features that Babel might be. Perhaps it is worth it to just avoid those features to get the enhanced tooling...

@jbaxleyiii
Copy link
Contributor Author

So far the spread operator is the only big miss I've seen. I love ...foo but I do think the tooling out weighs it. Plus the timeline for it being added is within the next month or so 🎉

@stubailo
Copy link
Contributor

@jbaxleyiii I'm going to try to merge like all of these PRs today, if that's fine with you?

@jbaxleyiii
Copy link
Contributor Author

@stubailo that would be great! I'd recommend merging #11 instead of this one though since it will let us adopt fully typed more slowly

@stubailo
Copy link
Contributor

@jbaxleyiii after some in-depth conversation with @helfer I feel like it might be better to adopt Flow instead of TypeScript after all for the following reasons (assuming they both support basic typing requirements):

  1. It will be nicer for potential users of this library that it's a codebase built using Babel that they can understand, with .js file extensions. I think Flow looks a lot more like "annotations on top of JavaScript" vs. TypeScript which is more like "a new programming language that looks like JavaScript".
  2. People looking to use Apollo will have to accept using tools developed by Facebook, specifically GraphQL. It might be easier to convince those people that Flow is a reasonable choice than also having to trust Microsoft.
  3. After looking into TypeScript a bit, it looks like it doesn't do well in cases where not all of your stuff is typed - it's a bit harder to incrementally adopt (as you've seen in these two PRs)

The next step for me is, I'm going to take your Flow PR and try to set up the right tooling in Atom to get autocompletion, etc. If it works well I think I'm going to call it in favor of Flow. If it's too hard to set up I'm going to do the same with TypeScript to see if it's significantly better.

Does this sound like a reasonable choice?

@jbaxleyiii
Copy link
Contributor Author

@stubailo that sounds good to me. I like typescript but flow is way easier to get into!

@stubailo
Copy link
Contributor

I'm starting to go back on this, after trying to get Flow to work... have you actually been able to get it to report a useful type error? Like it doesn't actually seem to check if the fields we are using are on the GraphQL AST...?

@mquandalle
Copy link

On @stubailo point 3., maybe I’m underestimating the amount of development that went into the Apollo client, but is the difficulty to incrementally adopt typing is such a big deal? Maybe it’s worth spending a few days to have 100% type coverage (whichever type system end up being chosen)?

@stubailo
Copy link
Contributor

is the difficulty to incremental adopt typing is such a big deal?

I agree! I'm just wondering about stuff like NPM packages and the like. In TypeScript it seems like we basically need to have 100% coverage on these? I could be misinterpreting though.

@mquandalle
Copy link

Haven’t tried it yet but Typescript 1.8 introduced the ability to mix JavaScript and Typescript in the same application (see the release notes). (and there are already many libraries on DefinitelyTyped)

@stubailo
Copy link
Contributor

Can't change type of var on the fly

The way you do it is by defining a new var:

const myVar: string | number;
const myNumberVar = myVar as number;

I think it is probably smart enough not to actually make a new variable there.

@jbaxleyiii
Copy link
Contributor Author

@stubailo you fixed all the typing errors 🎉 🎉

@jbaxleyiii jbaxleyiii changed the title [WIP] Static typing with typescript Static typing with typescript Mar 21, 2016
@stubailo
Copy link
Contributor

Yeah arguably a lot of them were actual flaws in the code!

@stubailo
Copy link
Contributor

I'm really loving VS Code btw. This is super dope.

@jbaxleyiii
Copy link
Contributor Author

@stubailo the auto type generation is really great as a consumable:

import { Document } from 'graphql';
export declare function readQueryFromStore({store, query}: {
    store: Object;
    query: Document | string;
}): Object;
export declare function readFragmentFromStore({store, fragment, rootId}: {
    store: Object;
    fragment: Document | string;
    rootId: string;
}): Object;

@stubailo
Copy link
Contributor

@jbaxleyiii so should I merge this branch now, or what? Also, are you working on this full-time? If so, we should get on some kind of chat channel or something.

@jbaxleyiii
Copy link
Contributor Author

@stubailo I'm all for the merge! I can go through tonight and update my network interface to be typed 💯 I'm working about 30% on this right now as I clean up and add a few quick features to our app that just launched. But I pretty much always have slack open so a chat would be awesome!

apollostack.slack.com is available

@stubailo
Copy link
Contributor

@jbaxleyiii can you join me on the MeteorChef slack? http://slack.themeteorchef.com/

stubailo pushed a commit that referenced this pull request Mar 21, 2016
Static typing with typescript
@stubailo stubailo merged commit e8d4391 into master Mar 21, 2016
@jbaxleyiii jbaxleyiii deleted the typescript branch March 22, 2016 02:24
@arlair
Copy link

arlair commented Mar 31, 2016

I don't know if this is still helpful, but I believe you can use any JavaScript if you require it (not import as that does needs types).

const importEverything = require('myJavaScriptLibrary');
const { importThisOneThing } = require('myJavaScriptLibrary');

@stubailo
Copy link
Contributor

Ooh, good to know! So far, I've been able to find type definitions online for every library we are using, but it will be helpful to know we don't absolutely need them!

@arlair
Copy link

arlair commented Mar 31, 2016

I noticed you have typings reference comments shown in the code in the pull request. I believe that is also not required anymore with recent versions of TypeScript. Good luck.

@stubailo
Copy link
Contributor

Yep, you'll see that the master branch doesn't have those anymore!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants