Description
Discussed in #6013
Originally posted by JoshuaKGoldberg November 7, 2022
Suggestion
We write code like this very frequently:
const parserServices = util.getParserServices(context);
const checker = parserServices.program.getTypeChecker();
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
const type = checker.getTypeAtLocation(node);
It's a little burdensome.
@bradzacher and I were chatting in a pairing about how it might be convenient to make a wrapper around this, for convenience. Vague first draft:
declare const typeUtils: {
[K in keyof ts.TypeChecker]:
(services: ParserServices, node: TSESTree.Node) => ReturnType<ts.TypeChecker[K]>;
};
const type = typeUtils.getTypeAtLocation(parserServices, node);
We'd probably want to export this as a publicly available & documented API, so it's not confusing to consumers why our source code doesn't look like examples.
One downside would be that we're obfuscating how to use TypeScript APIs. I hate to add to complexity of understanding these already hard-to-understand things...
We ended up with #6013 (comment): putting the types right on the parser services.
I would say we could probably go one step further and just offer all of this off of the parser serivces!
For example:
type ParserServices = { getTypeAtLocation(node: TSESTree.Node): ReturnType<ts.TypeChecker['getTypeAtLocation']>; }; const parserServices = util.getParserServices(context); parserServices.getTypeAtLocation(node);That would make it even more straight-forward for people to use the tooling!