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

Add typeChecker API to get the inferred type arguments of call expression #59637

Closed
6 tasks done
zcbenz opened this issue Aug 15, 2024 · 4 comments · Fixed by #60201
Closed
6 tasks done

Add typeChecker API to get the inferred type arguments of call expression #59637

zcbenz opened this issue Aug 15, 2024 · 4 comments · Fixed by #60201
Labels
Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@zcbenz
Copy link

zcbenz commented Aug 15, 2024

🔍 Search Terms

infer type arguments function call expression

✅ Viability Checklist

⭐ Suggestion

interface TypeChecker {
  getTypeArgumentsOfSignature(signature: Signature): readonly Type[];
}

📃 Motivating Example

For the below code, the proposed API is supposed to return [ "text" ] for the Passthrough("text") node.

function Passthrough<T>(value: T) {
  return value;
}

let str = Passthrough("text");

💻 Use Cases

In my own case, I'm writing a TypeScript to C++ compiler and getting the inferred type argument is essential for translating the generic function call to C++.

There are also a few other open source projects getting the information by hacking TypeScript's internals:

https://github.com/GoogleFeud/ts-macros/blob/e65480a7bc54107e935e9a95ecbb4f3825f2d6e2/src/utils.ts#L259-L270

https://github.com/mxsdev/ts-type-explorer/blob/3b0bb21f574ebb0d70aac84c37e81e1df0b1d9e4/packages/api/src/util.ts#L725-L750

https://github.com/johnW-ret/express-openapi-gen/blob/885e498066f51fccaa00615f0b46b070788477c9/src/index.ts#L45C18-L84

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Aug 15, 2024
@weswigham
Copy link
Member

We don't have a function for this internally (weird, I know - we always operate over and compose TypeMapper objects, not concrete type arguments), but I think internally to the checker, the implementation is just

function getTypeArgumentsForResolvedSignature(signature: Signature) {
    return instantiateTypes((signature.target || signature).typeParameters, signature.mapper);
}

(so long as you're OK with an unresolved signature returning its' input type parameter list). You can't implement it publicly because .target, .mapper, and instantiateTypes are all internal, but it seems like a reasonable thing to want to know about a resolved signature.

@RyanCavanaugh
Copy link
Member

Approved to expose the above function

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Aug 16, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 16, 2024
@Jack-Works
Copy link
Contributor

I have the following use case of the type checker public API. Is that impossible since

You can't implement it publicly because .target, .mapper, and instantiateTypes are all internal

  1. Get the global Iterable type
  2. Instantiate it with any: Iterable<any, any, any>
  3. Compare it with another type via checker.isTypeAssignableTo

@SukkaW
Copy link

SukkaW commented Sep 29, 2024

I have the following use case of the type checker public API. Is that impossible since

You can't implement it publicly because .target, .mapper, and instantiateTypes are all internal

  1. Get the global Iterable type
  2. Instantiate it with any: Iterable<any, any, any>
  3. Compare it with another type via checker.isTypeAssignableTo

TL; DR:

How can I use TypeScript's type checker API to determine if a ts.Type is iterable (a.k.a. assignable to Iterable<any, any, any>).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
5 participants