Add and change ports and flags with confidence and ease. Elm knows about your types, so why shouldn't TypeScript?
Sign up to receive an Early Access discount code.
The Community Edition has the same type-safety as the Pro Edition. You can upgrade to elm-ts-interop pro any time to get the additional tools for productivity and convenience.
Setup the free Community EditionIt feels just like using elm/json to build Decoders and Encoders.
module Definitions exposing
( Flags
, flags
, gotUserInfo
, logEvent
)
import Event exposing (Event)
import Os exposing (Os)
import TsJson.Decode as TsDecode
import TsJson.Encode as TsEncode
type alias Flags =
{ os : Os }
flags : TsDecode.Decoder Flags
flags =
TsDecode.field "os" Os.decoder
|> TsDecode.map Flags
logEvent : TsEncode.Encoder Event
logEvent =
Event.encoder
gotUserInfo : TsDecode.Decoder { first : String, last : String }
gotUserInfo =
TsDecode.succeed (\first last -> { first = first, last = last })
|> TsDecode.andMap (TsDecode.field "first" TsDecode.string)
|> TsDecode.andMap (TsDecode.field "last" TsDecode.string)
You can run the CLI on your local machine, or on your CI server. It gives you a TypeScript declaration file that lets TypeScript know about the types of the ports and flags you defined.
$ elm-ts-interop-pro
✅ Generated src/Main/index.d.ts
Can you spot the errors in this example? Hint: look for the red squiggly line, and hover to read the TypeScript error. Ctrl+space is handy for type-aware auto-complete! Now see if you can fix the error in the interactive editor!
Because we used elm-ts-interop, TypeScript now knows what types are valid for our ports and flags!
Use the generated InteropPorts module to easily send and receive type-safe ports and decode your flags.
module Main exposing (main)
import Browser
import Definitions
import Event
import Html exposing (..)
import InteropPorts
import Json.Decode
main : Program Json.Decode.Value Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
type alias Model =
Result String Definitions.Flags
init : Json.Decode.Value -> ( Model, Cmd Msg )
init flags =
case InteropPorts.decodeFlags flags of
Err flagsError ->
( Err <| Json.Decode.errorToString flagsError
, Cmd.none
)
Ok okFlags ->
( Ok okFlags
, InteropPorts.logEvent
{ severity = Event.Info
, message = "Hello!"
}
)
type Msg
= GotUser { first : String, last : String }
subscriptions : Model -> Sub Msg
subscriptions _ =
InteropPorts.toElm
|> Sub.map
(\toElm ->
case toElm of
InteropPorts.GotUserInfo user ->
GotUser user
)
If you're not satisfied, contact me within the first 14 days and I'll send you a full refund.
Improve your Elm workflow with the pro tools.
Pro command-line tool
Scaffolding tool to easily generate Encoders and Decoders
Pay once, own it forever