Skip to content

Instantly share code, notes, and snippets.

@vincentjames501
Created January 11, 2020 00:29
Show Gist options
  • Save vincentjames501/169b04680f0d05a84d433e5956688d0d to your computer and use it in GitHub Desktop.
Save vincentjames501/169b04680f0d05a84d433e5956688d0d to your computer and use it in GitHub Desktop.
TypeScript + Clojure
;; TypeScript + Clojure
(deftype User {
:id Num
:name Str
Optional<:age> Num ;; Key may be missing, but if present a Num value is present
:address <Str | Nil> ;; Key is present, but value can be Nil
:orders Seq<Order> ;; Seq is super type of Vec/ArrayList/etc
})
;; Supports Intersections
(deftype ExtendedUser <User & {
:anything Any ;; Any type is special, like TS
:metadata {:some-num Num} ;; Can describe nested maps
Keyword Str ;; This is special, it will accept any other properties so long as the key is a Keyword and value a String
}>)
(deftype Error {
:status <:success | :failure> ;; Supports union types
:message Str
})
;; Defining function types
(deftype CallbackFn [<Error | Nil>] => Any)
(deftype TwoArgCallbackFn [User <Error | Nil>] => Boolean)
;; Type inferred as Long
(def some-const 1)
;; Using explicit type
(def cb: CallbackFn #(println %))
(def cb2: CallbackFn
(fn [e] ;; Inferred as <Error | Nil>
(println e)))
;; When not using the explicit type, Inferred as ([Any] => Any)
(def cb3 #(println %))
(def default-error: Error
{:status :failure
:message "An unknown error occurred"})
;; Note, omitting the type defaults the return to Any and parameters to Any types
(defn change-user-name:<Error | User>
[user: User name: String]
(cond
(str/blank? name)
{:status :failure
:message "Name is blank"}
(db/name-taken? (:id user))
{:status :failure
:message "Name already taken"}
:else
(if (db/update-name! (:id user) name)
(assoc user :name name)
default-error)))
;; Sample core functions
(defn <T K V>assoc:<T & {K V}>
[map: <T | Nil> key: K val: V]
(clojure.lang.RT/assoc map key val))
;; keyof special syntax, T[K] is the value type in map
(defn <T <K extends keyof T> N>get:T[K]
([map: <T | Nil> key: K]
(clojure.lang.RT/get map key))
([map: <T | Nil> key: K not-found: N]
(clojure.lang.RT/get map key not-found)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment