newtype
is a construct that allows you to create a nominal type from another type. (Recall that Haskell and Typescript are both structurally typed.) One use case is to allow differentiation of two values with the same underlying type, where one value needs to follow a separate set of constraints.strings
; however, we have several functions that want to ensure they only receive either fiat symbols or crypto symbols. How can we enlist the type system's help here, while keeping our values as regular strings?newtype
s. Also note that this pattern doesn't actually allow you to enforce invariants about the derived types. For that, it might be better to actually make your newtype
a separate type altogether, with its own internal logic. (For example, you can implement the type as a traditional OOP class with methods, or as an ADT with a functor, etc. instances for manipulation.)[Unique]
object key is a trick for hiding the tag from an editor's autocomplete (credits to Dan Freeman's great article for this trick).type CryptoCurrency
which is really just a string
, but will be handled nominally rather than structurally, such that if we try to pass a string
to a function that expects a CryptoCurrency
, we will get a type error. Contrast this with export type CryptoCurrency = string
, which would be like the Haskell type synonym type CryptoCurrency = String
instead of newtype CryptoCurrency = String
.CryptoCurrency
, or throws an error. Note that when transpiled to Javascript, the function's non-error case is actually a no-op -- the newtype
lives entirely in the type system.Record
:serializeDate = (date: DateRecord): string
and a deserializer parseDate = (str: string): DateRecord
, both of which do some validation. We can improve type safety and reduce the chances of deserialization errors by changing string
in these signatures to a SerializedDate
newtype
. Now, we can be sure that we are only ever passing the "right" strings to parseDate
. We can also go a bit further by typing all other sources (like API responses) with SerializedDate
where appropriate.