This is a interview practice question from BFE.dev.
Currying is a useful technique used in JavaScript applications.
Please implement a
curry()
function, which accepts a function and return a curried one.
The solution is pretty simple, but when implementing it with TypeScript the compiler will throw a warning about my usage of this
.
// This is a JavaScript coding problem from BFE.dev
function curry(fn: (...args: any[]) => any): (...args: any[]) => any {
return function curried(...args: any[]): any {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return curried.bind(this, ...args);
}
}
}
The warning:
'this' implicitly has type 'any' because it does not have a type annotation.
So then I have two questions:
- What should
this
be in this context? - How can I type
this
to be correct based on the answer to #1?
For #1 I looked at Arnav Aggarwal's "Simple Rules to this
in JavaScript."
- If the
new
keyword is used when calling the function,this
inside the function is a brand new object.- If
apply
,call
, orbind
are used to call/create a function,this
inside the function is the object that is passed in as the argument.- If a function is called as a method, such as
obj.method()
—this
is the object that the function is a property of.- If a function is invoked as a free function invocation, meaning it was invoked without any of the conditions present above,
this
is the global object. In a browser, it is thewindow object
. If in strict mode ('use strict'),this
will beundefined
instead of the global object.- If multiple of the above rules apply, the rule that is higher wins and will set the
this
value.- If the function is an ES2015 arrow function, it ignores all the rules above and receives the
this
value of its surrounding scope at the time it is created.
I'm pretty sure #1 can be eliminated (probably?), but #2, #3, and #4 all seem like they could be true at runtime. So then, how can I type this
properly?
-
\$\begingroup\$ I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate. \$\endgroup\$Sᴀᴍ Onᴇᴌᴀ– Sᴀᴍ Onᴇᴌᴀ ♦2023年10月02日 21:41:39 +00:00Commented Oct 2, 2023 at 21:41
1 Answer 1
You can annotate this
in the following way:
function curry(fn: (...args: any[]) => any): (this: CallableFunction, ...args: any[]) => any {
...
In your context, the code is calling apply
and bind
on this
. In order to do that this
may be typed as a CallableFunction
.
-
\$\begingroup\$ @SᴀᴍOnᴇᴌᴀ I don't really see why this was closed. The code runs exactly as intended, but gets TypeScript warnings. TypeScript has (mostly) nothing to do with actual runtime behavior. \$\endgroup\$Christopher Fimbel– Christopher Fimbel2023年10月02日 20:46:35 +00:00Commented Oct 2, 2023 at 20:46
-
\$\begingroup\$ I apologize- it wasn't obvious that it was just a warning. After going through CR meta I realize in general code with warnings are acceptable and I have updated your question to make it clear that it is a warning instead of an error. \$\endgroup\$2023年10月02日 21:33:42 +00:00Commented Oct 2, 2023 at 21:33
Explore related questions
See similar questions with these tags.