TypeCheck v0.12.0 released
Version 0.12.0 of TypeCheck has been released! 🚀
Additions:
Per-dependency configuration
The default options used are now fetched from the application configuration.
This means that you can configure a default for your app as well as for each of your dependencies(!) by adding config :app_name, :type_check […]
to your configuration file(s).
(This configuration can then further be overridden per module, which was already possible in earlier versions.)
Building types and checks for external functions
If you want to use types from modules outside of your control, until now you had to manually recreate them. Now, the TypeCheck.External module allows fetching the ‘normal’ types and specs from a compiled module. Specifically:
-
TypeCheck.External
module, with functions to work with typespecs in modules outside of your control.-
fetch_spec
to build a TypeCheck type from any function that has a@spec
. -
fetch_type
to build a TypeCheck type from any@type
. -
enforce_spec!
to wrap a call to any function that has a@spec
with a runtime type-check on the input parameters and return value. -
apply
andapply!
to wrap a call to any function with the function spec type that you give it.
-
iex> TypeCheck.External.enforce_spec!(Kernel.abs(-13))
13
iex> TypeCheck.External.enforce_spec!(Kernel.abs("hi"))
** (TypeCheck.TypeError) At lib/type_check/external.ex:175:
`"hi"` is not a number.
This functionality is still very new, so we consider it to be a little experimental. In the near future, it might be integrated further with the rest of the library. For instance, we might add syntactic sugar to make ‘type overrides’ easier.
I want to take this opportunity to thank @orsinium greatly. Both the idea and the implementation of this functionality is his work! :star_struck:
Defstruct!
TypeCheck.Defstruct.defstruct!
, a way to combine defstruct
, @enforce_keys
and the creation of the struct’s type, reducing boilerplate and the possibility of mistakes. (c.f. #118 )
Example:
defmodule User do
use TypeCheck
use TypeCheck.Defstruct
defstruct!(
name: "Guest" :: String.t(),
age: _ :: non_neg_integer()
)
end
is syntactic sugar for:
defmodule User do
use TypeCheck
use TypeCheck.Defstruct
@type! t() :: %User{
name: String.t(),
age: non_neg_integer()
}
@enforce_keys [:age]
defstruct [:age, name: "Guest"]
end
Fixes:
- Long-standing issue where Dialyzer would sometimes complain in apps using TypeCheck is resolved. (c.f. #95)
-
Creation of the new
maybe_nonempty_list
type will no longer get stuck in an infinite loop on creation. (c.f. #120)
This new release is just in time for ElixirConf.EU where I will be speaking about TypeCheck. I look forward to see a lot of you there (live or virtually)!
There will also be stickers! 😊
As always, you can find TypeCheck on Hex.PM, on GitHub and on the Elixir forum.
Read next ThinkingElixir 102: Machine Learning in Elixir with Sean Moriarity