С текущей альфа-спецификацией, чтобы использовать один и тот же набор ключей как для спецификации keys
, так и для проверки, по крайней мере, одного существующего, вам необходимо использовать макрос.(Предстоящая альфа-версия спецификации 2 решает эту проблему, предоставляя больше управляемых данными API для создания спецификаций.)
Вот краткий набросок для вашего конкретного примера:
(defmacro one-or-more-keys [ks]
(let [keyset (set (map (comp keyword name) ks))]
`(s/and (s/keys :opt-un ~ks)
#(some ~keyset (keys %)))))
(s/def ::my-spec (one-or-more-keys [::foo ::bar]))
(s/conform ::my-spec {:bar nil})
=> {:bar nil}
(s/conform ::my-spec {:baz nil})
=> :clojure.spec.alpha/invalid
В качестве альтернативы, вы можете просто определитьдважды наберите ключ и используйте аналогичный предикат с s/and
.