How do you type a 3 argument curried function in typescript?
Or how do you define multiple signatures for a returned function
I'm trying to make a curried function but I'm having trouble with the definition overloads. In specific if you call parallelMap
with one argument, you can call the next argument with 1 or 2 arguments. However the def is marked as invalid.
[ts] Overload signature is not compatible with function implementation. [2394]
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
Full implementation;
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
concurrency: number,
func?: (data: T) => R | Promise<R>,
iterable?: AnyIterable<T>,
)
if (func === undefined)
return <A, B>(curriedFunc: (data: A) => B
if (iterable === undefined)
return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
return _parallelMap<T, R>(concurrency, func, iterable)
Thanks!
javascript typescript iterator currying
add a comment |
Or how do you define multiple signatures for a returned function
I'm trying to make a curried function but I'm having trouble with the definition overloads. In specific if you call parallelMap
with one argument, you can call the next argument with 1 or 2 arguments. However the def is marked as invalid.
[ts] Overload signature is not compatible with function implementation. [2394]
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
Full implementation;
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
concurrency: number,
func?: (data: T) => R | Promise<R>,
iterable?: AnyIterable<T>,
)
if (func === undefined)
return <A, B>(curriedFunc: (data: A) => B
if (iterable === undefined)
return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
return _parallelMap<T, R>(concurrency, func, iterable)
Thanks!
javascript typescript iterator currying
add a comment |
Or how do you define multiple signatures for a returned function
I'm trying to make a curried function but I'm having trouble with the definition overloads. In specific if you call parallelMap
with one argument, you can call the next argument with 1 or 2 arguments. However the def is marked as invalid.
[ts] Overload signature is not compatible with function implementation. [2394]
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
Full implementation;
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
concurrency: number,
func?: (data: T) => R | Promise<R>,
iterable?: AnyIterable<T>,
)
if (func === undefined)
return <A, B>(curriedFunc: (data: A) => B
if (iterable === undefined)
return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
return _parallelMap<T, R>(concurrency, func, iterable)
Thanks!
javascript typescript iterator currying
Or how do you define multiple signatures for a returned function
I'm trying to make a curried function but I'm having trouble with the definition overloads. In specific if you call parallelMap
with one argument, you can call the next argument with 1 or 2 arguments. However the def is marked as invalid.
[ts] Overload signature is not compatible with function implementation. [2394]
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
Full implementation;
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
concurrency: number,
func?: (data: T) => R | Promise<R>,
iterable?: AnyIterable<T>,
)
if (func === undefined)
return <A, B>(curriedFunc: (data: A) => B
if (iterable === undefined)
return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
return _parallelMap<T, R>(concurrency, func, iterable)
Thanks!
javascript typescript iterator currying
javascript typescript iterator currying
edited Nov 15 '18 at 15:54
reconbot
asked Nov 14 '18 at 23:52
reconbotreconbot
2,62953657
2,62953657
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:
[The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.
Your first two overloads have the same parameter types, so the second overload will never be used. That means if you call parallelMap()
with one argument, it will return a two-argument function and that's it. It does not return a one-argument function.
Let's remedy that. The solution here is when you call parallelMap()
with one argument, you want to return an overloaded function, instead of a function of just one argument or just two arguments.
Additionally, you want the generic type parameters to be on that returned function, since when you call parallelMap(concurrency)
you don't know at that point what T
and R
will end up being.
So replace those first two signatures with this:
export function parallelMap(concurrency: number):
<T,R>(func: (data: T) => R
Now that says "if you call parallelMap()
with one argument, it will return another function which can be called with two arguments of type XXX and YYY and return ZZZ, and it can also be called with one argument of type XXX and return a function from YYY to ZZZ."
Now it should mostly work. Notice that because you are using overloads, the following code isn't exactly correct:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
After all, none of the overload call signatures accept a possibly undefined
third argument. You either call it with two or three defined arguments. So you should change that to something like:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
which calls two different overloads of parallelMap()
depending on whether curriedIterable
is defined.
Okay, hope that helps. Good luck!
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I getAsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)
– reconbot
Nov 15 '18 at 15:52
Maybe you're not using--strictNullChecks
? If so that's why you're not seeing the other error when usingundefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.
– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
Oh, sure... you should make the returned function generic in<T, R>
and notparallelMap()
itself. Updated the answer.
– jcalz
Nov 16 '18 at 2:23
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310509%2fhow-do-you-type-a-3-argument-curried-function-in-typescript%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:
[The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.
Your first two overloads have the same parameter types, so the second overload will never be used. That means if you call parallelMap()
with one argument, it will return a two-argument function and that's it. It does not return a one-argument function.
Let's remedy that. The solution here is when you call parallelMap()
with one argument, you want to return an overloaded function, instead of a function of just one argument or just two arguments.
Additionally, you want the generic type parameters to be on that returned function, since when you call parallelMap(concurrency)
you don't know at that point what T
and R
will end up being.
So replace those first two signatures with this:
export function parallelMap(concurrency: number):
<T,R>(func: (data: T) => R
Now that says "if you call parallelMap()
with one argument, it will return another function which can be called with two arguments of type XXX and YYY and return ZZZ, and it can also be called with one argument of type XXX and return a function from YYY to ZZZ."
Now it should mostly work. Notice that because you are using overloads, the following code isn't exactly correct:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
After all, none of the overload call signatures accept a possibly undefined
third argument. You either call it with two or three defined arguments. So you should change that to something like:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
which calls two different overloads of parallelMap()
depending on whether curriedIterable
is defined.
Okay, hope that helps. Good luck!
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I getAsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)
– reconbot
Nov 15 '18 at 15:52
Maybe you're not using--strictNullChecks
? If so that's why you're not seeing the other error when usingundefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.
– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
Oh, sure... you should make the returned function generic in<T, R>
and notparallelMap()
itself. Updated the answer.
– jcalz
Nov 16 '18 at 2:23
add a comment |
Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:
[The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.
Your first two overloads have the same parameter types, so the second overload will never be used. That means if you call parallelMap()
with one argument, it will return a two-argument function and that's it. It does not return a one-argument function.
Let's remedy that. The solution here is when you call parallelMap()
with one argument, you want to return an overloaded function, instead of a function of just one argument or just two arguments.
Additionally, you want the generic type parameters to be on that returned function, since when you call parallelMap(concurrency)
you don't know at that point what T
and R
will end up being.
So replace those first two signatures with this:
export function parallelMap(concurrency: number):
<T,R>(func: (data: T) => R
Now that says "if you call parallelMap()
with one argument, it will return another function which can be called with two arguments of type XXX and YYY and return ZZZ, and it can also be called with one argument of type XXX and return a function from YYY to ZZZ."
Now it should mostly work. Notice that because you are using overloads, the following code isn't exactly correct:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
After all, none of the overload call signatures accept a possibly undefined
third argument. You either call it with two or three defined arguments. So you should change that to something like:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
which calls two different overloads of parallelMap()
depending on whether curriedIterable
is defined.
Okay, hope that helps. Good luck!
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I getAsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)
– reconbot
Nov 15 '18 at 15:52
Maybe you're not using--strictNullChecks
? If so that's why you're not seeing the other error when usingundefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.
– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
Oh, sure... you should make the returned function generic in<T, R>
and notparallelMap()
itself. Updated the answer.
– jcalz
Nov 16 '18 at 2:23
add a comment |
Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:
[The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.
Your first two overloads have the same parameter types, so the second overload will never be used. That means if you call parallelMap()
with one argument, it will return a two-argument function and that's it. It does not return a one-argument function.
Let's remedy that. The solution here is when you call parallelMap()
with one argument, you want to return an overloaded function, instead of a function of just one argument or just two arguments.
Additionally, you want the generic type parameters to be on that returned function, since when you call parallelMap(concurrency)
you don't know at that point what T
and R
will end up being.
So replace those first two signatures with this:
export function parallelMap(concurrency: number):
<T,R>(func: (data: T) => R
Now that says "if you call parallelMap()
with one argument, it will return another function which can be called with two arguments of type XXX and YYY and return ZZZ, and it can also be called with one argument of type XXX and return a function from YYY to ZZZ."
Now it should mostly work. Notice that because you are using overloads, the following code isn't exactly correct:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
After all, none of the overload call signatures accept a possibly undefined
third argument. You either call it with two or three defined arguments. So you should change that to something like:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
which calls two different overloads of parallelMap()
depending on whether curriedIterable
is defined.
Okay, hope that helps. Good luck!
Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:
[The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.
Your first two overloads have the same parameter types, so the second overload will never be used. That means if you call parallelMap()
with one argument, it will return a two-argument function and that's it. It does not return a one-argument function.
Let's remedy that. The solution here is when you call parallelMap()
with one argument, you want to return an overloaded function, instead of a function of just one argument or just two arguments.
Additionally, you want the generic type parameters to be on that returned function, since when you call parallelMap(concurrency)
you don't know at that point what T
and R
will end up being.
So replace those first two signatures with this:
export function parallelMap(concurrency: number):
<T,R>(func: (data: T) => R
Now that says "if you call parallelMap()
with one argument, it will return another function which can be called with two arguments of type XXX and YYY and return ZZZ, and it can also be called with one argument of type XXX and return a function from YYY to ZZZ."
Now it should mostly work. Notice that because you are using overloads, the following code isn't exactly correct:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
After all, none of the overload call signatures accept a possibly undefined
third argument. You either call it with two or three defined arguments. So you should change that to something like:
if (func === undefined)
return <A, B>(
curriedFunc: (data: A) => B
which calls two different overloads of parallelMap()
depending on whether curriedIterable
is defined.
Okay, hope that helps. Good luck!
edited Nov 16 '18 at 2:24
answered Nov 15 '18 at 1:36
jcalzjcalz
25.9k22244
25.9k22244
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I getAsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)
– reconbot
Nov 15 '18 at 15:52
Maybe you're not using--strictNullChecks
? If so that's why you're not seeing the other error when usingundefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.
– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
Oh, sure... you should make the returned function generic in<T, R>
and notparallelMap()
itself. Updated the answer.
– jcalz
Nov 16 '18 at 2:23
add a comment |
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I getAsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)
– reconbot
Nov 15 '18 at 15:52
Maybe you're not using--strictNullChecks
? If so that's why you're not seeing the other error when usingundefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.
– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
Oh, sure... you should make the returned function generic in<T, R>
and notparallelMap()
itself. Updated the answer.
– jcalz
Nov 16 '18 at 2:23
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
that multiple return syntax is a surprise!
– reconbot
Nov 15 '18 at 15:45
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I get
AsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)– reconbot
Nov 15 '18 at 15:52
Typescript doesn't have a problem with calling parallel map with an undefined. It resolves to the same types with your code or mine. I'm not resolving the types correctly when I curry however. I get
AsyncIterableIterator<>
when I call it with one argument at a time, but I get it correctly determined if I call it with two, and then one, (or all 3)– reconbot
Nov 15 '18 at 15:52
Maybe you're not using
--strictNullChecks
? If so that's why you're not seeing the other error when using undefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.– jcalz
Nov 15 '18 at 16:03
Maybe you're not using
--strictNullChecks
? If so that's why you're not seeing the other error when using undefined
as a parameter. Generally I recommend turning it on, but that's a matter or personal preference.– jcalz
Nov 15 '18 at 16:03
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
ohh you're right, I forgot it, still working on trying to get the generic types to apply to the curried functions
– reconbot
Nov 16 '18 at 1:53
1
1
Oh, sure... you should make the returned function generic in
<T, R>
and not parallelMap()
itself. Updated the answer.– jcalz
Nov 16 '18 at 2:23
Oh, sure... you should make the returned function generic in
<T, R>
and not parallelMap()
itself. Updated the answer.– jcalz
Nov 16 '18 at 2:23
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310509%2fhow-do-you-type-a-3-argument-curried-function-in-typescript%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown