https://github.com/codedownio/servant-typescript
TypeScript client generation for Servant
https://github.com/codedownio/servant-typescript
Last synced: 11 months ago
JSON representation
TypeScript client generation for Servant
- Host: GitHub
- URL: https://github.com/codedownio/servant-typescript
- Owner: codedownio
- License: bsd-3-clause
- Created: 2022-03-17T10:18:35.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2025-06-03T12:52:44.000Z (about 1 year ago)
- Last Synced: 2025-06-03T21:57:12.813Z (12 months ago)
- Language: Haskell
- Size: 41 KB
- Stars: 25
- Watchers: 2
- Forks: 7
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
# Welcome to `servant-typescript` [](https://hackage.haskell.org/package/servant-typescript) 
This library generates TypeScript client libraries for Servant.
First, make sure you have [TypeScript](https://hackage.haskell.org/package/aeson-typescript) instances defined for all of the types used in the API.
```haskell
data User = User {
name :: String
, age :: Int
, email :: String
} deriving (Eq, Show)
deriveJSONAndTypeScript A.defaultOptions ''User
```
If you need to generate lots of boilerplate instances, the functions in `aeson-typescript`'s [Recursive](https://hackage.haskell.org/package/aeson-typescript-0.4.0.0/docs/Data-Aeson-TypeScript-Recursive.html) module can be your friend.
I've used [recursivelyDeriveMissingTypeScriptInstancesFor](https://hackage.haskell.org/package/aeson-typescript-0.4.0.0/docs/Data-Aeson-TypeScript-Recursive.html#v:recursivelyDeriveMissingTypeScriptInstancesFor) to derive instances for the Kubernetes API.
Next, you'll need some Servant API:
```haskell
type UserAPI = "users" :> Get '[JSON] [User]
:<|> "albert" :> Get '[JSON] User
:<|> "isaac" :> Get '[JSON] User
```
Generating the library is as simple as this:
```haskell
main = writeTypeScriptLibrary (Proxy :: Proxy UserAPI) "/my/destination/folder/"
```
## Caveats
* This library doesn't yet support generating generic TypeScript functions to match generic TypeScript instances. You can hack around this by writing your own `getFunctions` and hardcoding them manually for the necessary types.
## Supporting additional combinators
If you use unusual Servant combinators in your API, you may need to define additional `HasForeign` instances to explain how to convert them to TypeScript. For example, when I work with the [servant-websockets](https://hackage.haskell.org/package/servant-websockets) package, I add instances like the following.
The same applies to custom `AuthProtect` combinators from [Servant.API.Experimental.Auth](https://hackage.haskell.org/package/servant-0.19/docs/Servant-API-Experimental-Auth.html), etc.
```haskell
instance HasForeign LangTS Text WebSocket where
type Foreign Text WebSocket = Text
foreignFor _ _ _ _ = "void"
instance HasForeign LangTSDecls [TSDeclaration] WebSocket where
type Foreign [TSDeclaration] WebSocket = [TSDeclaration]
foreignFor _ _ _ _ = []
```