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

Intersect function type or call signature with a different return type #30351

Closed
5 tasks done
jednano opened this issue Mar 13, 2019 · 3 comments
Closed
5 tasks done

Intersect function type or call signature with a different return type #30351

jednano opened this issue Mar 13, 2019 · 3 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@jednano
Copy link
Contributor

jednano commented Mar 13, 2019

Search Terms

Intersect function type with a different return type (Call Signature, Constructor, ConstructorParameters, ReturnType, Signature, FunctionSignature, Parameters, FunctionParameters).

Suggestion

This feature could be implemented in a number of different ways:

  1. Fix (...args: Parameters<T>) to somehow preserve the call signature (and TSDoc comments) of the original function T.
  2. Allow the ability to extract the call signature w/o the return type CallSignature<T> and/or the ability to define a return type by itself Returns<T>.
    • Better: CallSignature<T> => DifferentReturnType
    • Worse: T & Returns<DifferentReturnType>.

Use Cases

Functional programming, wrapper functions that modify or extend the return type only.

Examples

This is the current function I'm trying to create, but I'm struggling with typing the callback in such a way that I preserve the TSDocs and original call signature of TFunc.

function wrap<TFunc extends (...args: any[]) => any>(func: TFunc) {
	const wrapper = (...args: Parameters<TFunc>) => {
		// do stuff, return something
	}
	return wrapper /* as CallSignature<TFunc> => ReturnType<wrapper> */
}

Unfortunately, I can't even use ReturnType<wrapper> in this context. Wish I could!

Most importantly, the TSDoc comments should be preserved so that instead of this in vscode:

image

We get almost the same thing as calling the original function (minus the foo part):

image

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@RyanCavanaugh
Copy link
Member

It seems like this is already possible, or I've misunderstood / missed something?

function wrap<TFunc extends (...args: any[]) => any>(func: TFunc): (...args: Parameters<TFunc>) => number {
  const wrapper = (...args: Parameters<TFunc>) => {
    return 42;
  }
  return wrapper /* as CallSignature<TFunc> => ReturnType<wrapper> */
}

const k = wrap((a: string, b: boolean) => "");

image

@RyanCavanaugh RyanCavanaugh added the Needs More Info The issue still hasn't been fully clarified label Mar 19, 2019
@jednano
Copy link
Contributor Author

jednano commented Mar 19, 2019

@RyanCavanaugh, yes and no. Indeed, I'm super excited that version 3.4.0-dev.20190319 does show me what you've shown above; however, that's only half of the problem. The JSDoc tokens were not preserved in transition. Try this, please:

/**
 * does stuff!
 * @param a doc for a
 * @param b doc for b
 */
function foo(a: string, b: boolean) {
	return a + b.toString()
}

const k = wrap(foo)
k()

image

Notice how all the TSDoc comments were lost. I dropped a comment in a separate/existing issue about this, but I can't for the life of me find it.

@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript and removed Needs More Info The issue still hasn't been fully clarified labels Dec 16, 2021
@RyanCavanaugh
Copy link
Member

I'm glad we can help on the type side but figuring out when/if/how to copy over JS Doc comments is pretty fraught with peril. We can take that up as a separate suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants