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

question: performance impact of using this parameter that IS NOT type this #40704

Closed
tadhgmister opened this issue Sep 22, 2020 · 8 comments
Closed
Labels
Question An issue which isn't directly actionable in code

Comments

@tadhgmister
Copy link

Search Terms

this, polymorphic this type, this parameter, performance.
#35451, #6739

Question

I'd like a bit of clarification on this comment about this parameter causing drop in performance:
Does the presence of a this parameter cause drop in performance or using the this type? Specifically does doing method(this: void) have any negative performance impact?

There was a discussion over at typescript-eslint/typescript-eslint#2148 where there was some disagreement about whether adding this: void to methods would slow down typescript, I'd like our documentation to be accurate if possible.

So sorry for opening an issue for this, it just seemed weird to post a stack overflow question that very specifically was about another GitHub issue comment.

@RyanCavanaugh
Copy link
Member

@sandersn any ideas?

@tadhgmister
Copy link
Author

In case this helps reduce time someone need to search for relevant stuff:

You mentioned to look at the comments on #6739 and a search for the word "performance" brings up this comment which mentions seenThisKeyword which refers to the type this, also a bit of scanning through the source code looks like internally having no this parameter is treated the same way as setting it to void.

Thanks for the rapid response, really appreciate the work you all do! 🥇

@DanielRosenwasser
Copy link
Member

It really depends on the context. In that context in the binder, it is looking for this as a type annotation (e.g. let x: this) so it can track whether or not containing interfaces have to become generic on this. That's actually different from a this parameter.

In general, I would like to say that a this parameter has no negative performance impact except for the memory overhead of the node, the symbol, etc. In some cases, having an explicitly annotated this parameter is faster due to contextual typing, but this is rare.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Sep 22, 2020

To clarify further, that comment is still accurate because a "strict this" mode would require all methods in interfaces to implicitly have a this: this, making all interfaces with methods generic (which in general isn't cheap).

@tadhgmister
Copy link
Author

excellent, thank you so much for the clarification. :). Have a wonderful day!

@sandersn
Copy link
Member

An easy way to think of this is: the this type is expensive, the this parameter is cheap (it's just another parameter).
So this: this is expensive, but this: void is cheap.

this types and parameters actually predates the undefined type, so it's probably worth our time to revisit whether this: undefined should be defined to mean the same thing as this: void.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Sep 23, 2020

I don't know if we should - to me, this: void means "I don't care what you give me, I promise I won't witness it in a meaningful way" whereas this: undefined kind of means "you cannot bind this function with an object for as this".

In other words, void is an opaque value that you can only occasionally assign undefined to.

@tadhgmister
Copy link
Author

see Ryan's QA here and the below playground for why this: undefined should not have the same meaning as this: void, void means "not observed" where as undefined means "equal to the javascript value undefined" which do not represent the same thing.

(playground link)

declare let returnsVoid: ()=>void
declare let returnsUndefined: ()=> undefined
declare let returnsNumber: ()=> number

// returning void means the return value is un-observed, so any return value is assignable to it.
returnsVoid = returnsUndefined;
returnsVoid = returnsNumber;

// however returning undefined is not forgiving in the same way
returnsUndefined = returnsNumber;


declare let thisVoid: (this: void) => void;
declare let thisUndefined: (this: undefined) => void;
declare let thisNumber: (this: number) => void;

// by the same token, a function that does not observe the `this` parameter is perfectly valid to bind it to anything
thisUndefined = thisVoid
thisNumber = thisVoid

// and using this: undefined does not have the same desired behaviour.
thisNumber = thisUndefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants