core-typed

Olical 2025-05-19T21:45:48.126629Z

Had another go at pushing this runner forward and had to give up on the extensions for the multimethod I'm afraid. I found out I can just ignore the var though, so I'm annotating it with :no-check now which has got me past that part. I'm running into something weird though, I merge these maps:

(t/defalias TypedClojureExInfoData
  (t/HMap
   :mandatory {:form t/Any
               :type-error t/Keyword
               :env (t/HMap
                     :mandatory {:line t/Num
                                 :column t/Num
                                 :file t/Str})}))

(t/defalias TypeError
  (t/Merge
   TypedClojureExInfoData
   (t/HMap
    :mandatory {:message (t/Nilable t/Str)})))
But then when I use it here:
(t/ann error->str [background-check.runner/TypeError :-> t/Str])
I get an error because all of the properties are now "t/Any" other than the :message. Here's my env that shows this, sorry it's not pretty printed or anything.
│ {:env {p__118482__#0 (t/HMap :mandatory {:form t/Any, :type-error t/Any, :env t/Any, :message (t/Nilable t/Str)})}, :props (), :aliases {map__118809__#0 {:id p__118482__#0}, map__118809__#1 {:id p__118482__#0}, _error__#0 {:id p__118482__#0}, type-error__#0 {:id p__118482__#0, :path [(Key :type-error)]}, env__#0 {:id p__118482__#0, :path [(Key :env)]}, _form__#0 {:id p__118482__#0, :path [(Key :_form)]}, _data__#0 {:id p__118482__#0, :path [(Key :_data)]}, _message__#0 {:id p__118482__#0, :path [(Key :_message)]}}}

Olical 2025-05-23T11:02:39.228219Z

Ohhh that makes sense! Thank you, I should've tried this. I did see the concept of open/closed in the docs and considered closing them because it might prevent typo bugs but then thought "meh, it's Clojure-y to allow some extra keys sometimes". Better to be explicit, less confusion that way 🙂 thanks as always, I really really appreciate the tutoring you've been giving me with this. I'll have to spread the good word at reClojure in London on Monday 🎉

❤️ 1
Olical 2025-05-19T21:45:56.745519Z

Is this maybe a bug?

2025-05-19T23:02:22.744089Z

Oh, the problem is that both maps are open.

2025-05-19T23:03:18.227069Z

The right map is implicitly (t/HMap :optional {:form Any :type-error Any, :env Any ...})

2025-05-19T23:05:15.667159Z

So when you merge these maps, it combines (t/HMap :mandatory {:type-error Kw}) with (t/HMap :optional {:type-error Any}), which is (t/HMap :mandatory {:type-error (U Kw Any)}) => '{:type-error Any}

2025-05-19T23:05:41.745949Z

The easiest fix would be to use t/Assoc instead of t/Merge

2025-05-19T23:05:58.319669Z

You could also constrain the right map using :complete? true.

Olical 2025-05-28T10:21:45.400249Z

Ah interesting! I was also wondering how to assoc into the mandatory or optional parts of the HMap.

Olical 2025-05-26T20:18:46.549369Z

I couldn't work out the syntax for t/Assoc sadly, but I did get it working with a closed HMap and merge, yay!

❤️ 1
2025-05-27T19:04:51.878259Z

Merge is more flexible, but you might have missed a quote on the keyword singleton type: (t/Assoc TypedClojureExInfoData ':message (t/Nilable t/Str))

2025-05-27T19:06:06.133519Z

t/Assoc takes flat k/v pairs of types. (t/Val :message) is also written ':message.