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

chore(typings): Enabled noImplictAny and updated typings #1050

Conversation

david-driscoll
Copy link
Member

With this change compliation time and performance is improved


Testing the waters a little bit here, but this change doesn't include any of the massive changes to how the external typings are generated.

@david-driscoll
Copy link
Member Author

Current times

ES6

Files: 280
Lines: 28651
Nodes: 130697
Identifiers: 43291
Symbols: 8548835
Types: 483111
Memory used: 824318K
I/O read: 0.03s
I/O write: 0.13s
Parse time: 1.20s
Bind time: 0.70s
Check time: 25.11s
Emit time: 1.79s
Total time: 28.80s

AMD

Files: 249
Lines: 26793
Nodes: 123074
Identifiers: 41029
Symbols: 7474980
Types: 446931
Memory used: 720169K
I/O read: 0.03s
I/O write: 0.05s
Parse time: 0.72s
Bind time: 0.48s
Check time: 15.07s
Emit time: 0.65s
Total time: 16.93s

CommonJS

Files: 281
Lines: 27998
Nodes: 129465
Identifiers: 42856
Symbols: 8507685
Types: 481090
Memory used: 773381K
I/O read: 0.01s
I/O write: 0.08s
Parse time: 0.74s
Bind time: 0.49s
Check time: 16.75s
Emit time: 1.17s
Total time: 19.15s

New Times

ES6

Files: 281
Lines: 28737
Nodes: 131467
Identifiers: 43494
Symbols: 7811638
Types: 57411
Memory used: 165349K
I/O read: 0.02s
I/O write: 0.07s
Parse time: 0.91s
Bind time: 0.62s
Check time: 3.03s
Emit time: 0.74s
Total time: 5.29s

AMD

Files: 250
Lines: 26858
Nodes: 123798
Identifiers: 41237
Symbols: 6807061
Types: 55249
Memory used: 150986K
I/O read: 0.03s
I/O write: 0.06s
Parse time: 1.00s
Bind time: 0.66s
Check time: 3.26s
Emit time: 0.73s
Total time: 5.65s

CommonJS

Files: 282
Lines: 28084
Nodes: 130235
Identifiers: 43059
Symbols: 7775095
Types: 57210
Memory used: 168248K
I/O read: 0.02s
I/O write: 0.07s
Parse time: 0.78s
Bind time: 0.56s
Check time: 2.49s
Emit time: 0.71s
Total time: 4.54s

With this change compliation time and performance is improved
@kwonoj
Copy link
Member

kwonoj commented Dec 13, 2015

I personally like this changes and was considered quite while ago, wasn't sure if this is feasible for current codebases yet. Again, generally I prefer this idea to be strict manner.

Few suggestion for changes though,

  • would like to suggest to enable suppressImplicitAnyIndexErrors. Lot of cases in RxJS, it requires force casting to any to indexer based fields but does not gives quite benefit.
  • in case of build, you may need to update npm build script as well as tsconfig.json, since typescript project configuration is not actually being used in RxJS builds.

May have some comment in each code as well..

and cc @Blesh , @staltz here also since this'll impact code styles from now on expect opinions.

export function isPromise<T>(value: any | Promise<T>): value is Promise<T> {
Copy link
Member

Choose a reason for hiding this comment

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

Would you able to share some details of

  • what does generic does do?
  • reason to change return type from boolean?

Copy link
Member Author

Choose a reason for hiding this comment

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

The return type still behaves as a boolean, but it also acts as a type guard as well.

Given the following:

var value: Observable<T> | Promise<T>
if (isPromise(value)) {
    // to the type system value is now just Promise<T>
} else {
    // to the type system value is now just Observable<T>
}

@david-driscoll
Copy link
Member Author

@kwonoj I totally expect opinions, hence testing the waters first. 😄

As far as suppressImplicitAnyIndexErrors I never ran into a case, inside the current src, so I didn't even look at the flag. Now that might change once unit tests start to get converted over.

I tried to make the changes as non-invasive as possible, let me know if you notice something left behind. No actual code changes, just the types.

The one thing that impressed me was the drastic drop in memory usage, and the drastic reduction in types that were being tracked by the compiler.

@@ -0,0 +1,18 @@
import {Observable} from './Observable';
Copy link
Member

Choose a reason for hiding this comment

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

I think this file (types.ts) is not landed in current TOT of codebase, isn't it?

@kwonoj
Copy link
Member

kwonoj commented Dec 13, 2015

@david-driscoll Thanks for effort, this requires lot of changes. :)

One another suggestion in addition to above, I could see some changes like types.ts (https://github.com/david-driscoll/RxJS-1/blob/all-types-without-extras/src/types.ts) are included.

Given circumstances of PR itself is already huge due to nature of changes, I'd like to suggest to isolate PR as much as possible to not include directly related changes. Those refactoring can be separated into another PR, (maybe I presume too early?)

@kwonoj
Copy link
Member

kwonoj commented Dec 13, 2015

I'll hold on to add comment into each individual files for now to gather opinions regarding essence of this PR first. Once it's agreed to land this, detail can be updated from that point.

@david-driscoll
Copy link
Member Author

I left in types on purpose because of the usefulness of the common types for handing complicated declaration.

In some cases we see method signatures like (outerValue: T1, innerValue: T2, outerIndex: number, innerIndex: number) => TResult show up 3 times in a file with the function, Operator and Subscriber. It feels excessive and eats up a ton of space and is prone to failure. Also it opens up the ability to change what a _Selector is in a central location and be able to see that ripple through. I suppose they could be replaced out, but I felt they offered some value, so left them in at least as a discussion point.

@kwonoj
Copy link
Member

kwonoj commented Dec 13, 2015

I left in types on purpose because of the usefulness of the common types for handing complicated declaration.

: Yes, I do not deny those and I agree in general, suggestion is simply better to have separate PR for those. Once you're able to create another PR for those single changes only, that can be easily discussed in checked in, while this PR is on discussion. :)

In this PR currently, it contains 2 refactoring of

  • applying noimplicitany
  • adopting common type definition (types.ts)

and first change is quite huge, mixed discussion in this single PR could possibly delay check in of 2nd as well, and reviewer also requires additional effort (to discuss types.ts, have to open changes tab has >100 files). Please consider it as suggestion for purely logistics perspective.

@luisgabriel
Copy link
Contributor

Could you update the subject of the commit message to use lower case and present tense? Just a minor detail to keep the same pattern as the others commits in the history. ;)

@staltz
Copy link
Member

staltz commented Dec 14, 2015

I am in general favorable of merging this PR, but I haven't reviewed all the changes since there are many.

@benlesh
Copy link
Member

benlesh commented Dec 14, 2015

I am in general favorable of merging this PR, but I haven't reviewed all the changes since there are many.

Same.

@kwonoj
Copy link
Member

kwonoj commented Dec 15, 2015

OK, think we're in consensus. I'll drive initial effort for in-detail review for changes, and will bring in @Blesh , @staltz later before finally merge it.

Before proceed further comments, @david-driscoll would you kindly separate PR between 2 I commented above (#1050 (comment))?
I still believe separate PR serves better to deliver this vehicle into codebase.

@@ -35,9 +35,9 @@ export interface CoreOperators<T> {
projectResult?: (x: T, y: any, ix: number, iy: number) => R,
concurrent?: number) => Observable<R>;
flatMapTo?: <R>(observable: Observable<any>, projectResult?: (x: T, y: any, ix: number, iy: number) => R, concurrent?: number) => Observable<R>;
groupBy?: <R>(keySelector: (value: T) => string,
groupBy?: <TKey, R>(keySelector: (value: T) => string,
Copy link
Contributor

Choose a reason for hiding this comment

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

What about K instead of TKey?

It would keep the single letter pattern. It would also keep it similar to the signature used by RxJava.

@luisgabriel
Copy link
Contributor

There are a lot of good stuff in this PR. But I agree with @kwonoj here. This PR is too big to be reviewed properly.

I also have mixed feeling about some changes. For example:

-  if (result === errorObject) {
-    return new ErrorObservable(errorObject.e);
+  if (result as any === errorObject) {
+    return new ErrorObservable<any>(errorObject.e);
-const observableProto = (<KitchenSinkOperators<any>>Observable.prototype);
+const observableProto = (<KitchenSinkOperators<any>><any>Observable.prototype);
-Observable.prototype.exhaust = exhaust;
+(Observable.prototype as any).exhaust = exhaust;

I think this kind of change adds verbosity without many gains.

@kwonoj
Copy link
Member

kwonoj commented Dec 15, 2015

I'll put on hold reviewing this PR and wait for separation of changes for now.

@david-driscoll
Copy link
Member Author

@kwonoj I'll see if I have time tonight to gets things apart, might take a little bit of work.

@luisgabriel

-  if (result === errorObject) {
-    return new ErrorObservable(errorObject.e);
+  if (result as any === errorObject) {
+    return new ErrorObservable<any>(errorObject.e);

In the context of the method it makes sense, we could instead say it's of type T to match the return value. The big thing is errors in Rx aren't the same type as the observable might have contextually, in fact it adds value here, we're saying the error can actually be anything.

-const observableProto = (<KitchenSinkOperators<any>>Observable.prototype);
+const observableProto = (<KitchenSinkOperators<any>><any>Observable.prototype);

This could just be converted to const observableProto = (<any>Observable.prototype) or to maintain typing const observableProto: KitchenSinkOperators<any> = (<any>Observable.prototype);, without changes it does become an error with noImplictAny.

-Observable.prototype.exhaust = exhaust;
+(Observable.prototype as any).exhaust = exhaust;

This is again just a typing that can be corrected, I just hadn't corrected it. exhaust was conceptually moved to the extended space, but still exists on the base Observable.

@luisgabriel
Copy link
Contributor

In the context of the method it makes sense, we could instead say it's of type T to match the return value. The big thing is errors in Rx aren't the same type as the observable might have contextually, in fact it adds value here, we're saying the error can actually be anything.

I see the value of making the type parameter of ErrorObservable explicit. But what about the result as any casting?

const observableProto: KitchenSinkOperators<any> = (<any>Observable.prototype);

Much better. ;)

@david-driscoll
Copy link
Member Author

best we can do is (<any>result) === errorObject because the type of the result is not the same type as errorObject. TypeScript is helping us here saying they should never be equal, now under the covers that is clearly not the case because we pass around errorObject into result if an error occurs.

I just thought the as any syntax was easier to write/type than (<any>result), I don't care either way I don't really care how we cast it, lol.

@luisgabriel
Copy link
Contributor

Yeah, I was not questioning the casting syntax, but the casting itself. I prefer not to do casting in situations such as this one. But I suppose it is needed to enable noImplictAny.

@david-driscoll
Copy link
Member Author

we could make the errorObject: any, but then we'd lose it's definition, now I don't know if that matters to much.

@kwonoj kwonoj added the blocked label Dec 15, 2015
@kwonoj
Copy link
Member

kwonoj commented Dec 15, 2015

Marked as blocked for now to prevent accidental merging, #1077 should be resolved first.

@kwonoj
Copy link
Member

kwonoj commented Feb 2, 2016

@david-driscoll , I think #1086 is end conclusions for this PR's orignally aimed for and this can be closed by checking ing #1086 - is my understanding correct?

@david-driscoll
Copy link
Member Author

Yeah, we should be good for this issue.

@lock
Copy link

lock bot commented Jun 7, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants