In December last year I created the proof of concept (PoC) for an idea I have that seems a bit crazy, at least to me now. It’s a tool to search TypeScript functions and methods by their type signature.
Since I am quite happy with this PoC I decided to commit to the project and work on developing a real useful version.
I plan to share my experience in this devlog because I want to keep track of how the project evolves, what I learn and the things I discover along the way. Also, I guess it will be interesting and useful to others too. To get started I think it makes sense to share how I came up with this idea, what I’ve done already and what is ahead.
The crazy idea
I have been learning about functional programming for a while now. I started with Professor Frisby's Mostly Adequate Guide to Functional Programming and then went on to try out different languages, Elm, Haskell, Reason, Clojure, Scheme. Which is something I enjoy on itself and encourage you to do too. Learning other languages will give you new approaches and ways to solve problems that you can bring back to the language/s you use.
While playing around with Haskell for last year’s Advent of Code I used Hoogle (yeah, Hoogle, with H) a lot.
Hoogle is a Haskell API search engine, which allows you to search the Haskell libraries on Stackage by either function name, or by approximate type signature.
Stackage is a package manager for Haskell, with the guarantee that packages will work with each other.
Hoogle turned out to be a really useful tool during development. Which begged the question, why isn’t there such thing for TypeScript? I work with TypeScript on a daily basis and I think it would be a really good addition to the available tools.
The closest thing I found is Open Symbol by name in VS Code.
The proof of concept
I shared the idea with my friend Franco, who is much more pragmatic than I am, and he told my “Why don’t you build a PoC and see if it makes sense?”.
As a good PoC it had to be as simple as possible. A way to extract the type signatures from all the exported functions in a local directory and search them through a simple UI.
You can find it here. For now there is not much you can do with it and documentation is very basic.
By the way, I should give credit for the name, ts-earch
, to Franco.
Open questions
Developing the PoC convinced me that it is an idea worth working on. But, to be honest, it also left me with more questions than answers.
- Should I use actual TypeScript type signatures for search? Or should I come up with a simpler DSL? In Haskell that is not so much of a problem. Let’s compare the signature of
compose
in both languages.
compose :: (b -> c) -> (a -> b) -> a -> c
type Compose = <A, B, C>(f: (b: B) => C, g: (a: A) => B) => (a: A) => C
- What about type inference? Say we have a
Person
type, and a function that accepts a person, defined as:
interface Person {
name: string
}
const getName = (p: Person) => p.name
Searching for (x: { name: string }) => string
should return getName
even though the type matches implicitly. How to solve that, I have no idea yet.
- What is the best way to index the types for searching them?
- How to weigh and match types when searching?
These are a few of the open questions I have that I will have to solve. And I am sure there will be more questions along the way.
One step at a time
To get started it makes sense to have something that people can use and play around with. My short term goal is to adjust a few things and deploy ts-earch
with all the DefinitelyTyped packages available for search.
If you have any questions, suggestions or would like to collaborate on the project feel free to reach out to me on Twitter.
Stay tuned for more updates =D
Top comments (2)
Not a TS user, but looks like a really cool idea.
As per the questions, I'd go for the TS signatures for searching. All in all, ts-earch users will already be familiar with them, and forcing them to learn an additional DSL could hamper your adoption rate. Also, it's prone to have it's issues here and there, further difficulting the UX.
I have a similar-ish idea for a proyect (a "snippet-oriented", openly searchable, collaborative database) where I'll have to search leveraging code itself and descriptions. I might go for a machine learning/NLP solution. Although it's a tough road to take, you could look into it. Train some NN to sort out what method/function the user looks for based on the types mentioned. Overkill and hard? Absolutely; Fun? Hopefully.
And how to do inference/indexing/matching, I may be talking out of my a[s]{2}hole here, but I feel like some sort of tree datastructure may be of help here. For example, Scala types are sorta like this: oreilly.com/library/view/learning-...
If you could make something like that for TS, flexible enough so that you could add custom types based on the properties they contain, you could start matching them by traversing the tree.
Language theory is haaaard. I have a deep admiration for people who does that, and I'm sure you could find some here in dev.to. They'll be able to guide you a bit more with this.
Thanks for the comments! Very useful suggestions!
I haven't made up my mind yet about the query language. A "DSL" could be much simpler than the actual definition. For simple signatures there's no much change:
But for more complex ones it could become easier to type:
But I did not consider the fact that it would mean learning something new. That is a strong argument.
Yeah a ML/NPL solution could also be the case. But I guess it makes more sense your your idea (which, btw, is really cool).
Yeah, I will definitely take a look at how other languages do and even how TS itself does the type resolution. Now I implemented something pretty naive. Will write a bit more in the coming week/s.