FAQ
Why do I see type errors in an ArkType package in node_modules
?
This can occur due to incompatibilities between your tsconfig.json
and ours. It is totally harmless as long as your types are correct in source.
We highly recommend enabling skipLibCheck
in every TypeScript project to avoid false negatives like this and greatly improve editor performance.
Is there a way to create an async morph?
Other than handling it as a promise on the output object, no.
As it stands, it doesn't seem worth the significant complexity it would add to morphs in the type system.
If you have a compelling use case, let us know on this GitHub issue.
What's up with your type/Type casing?
You might have noticed in our documentation we use PascalCase for some Types and camelCase for others:
This distinction actually evolved from the rules we use for casing our internal TypeScript types:
-
Use
PascalCase
for...- Entities/non-generic types (e.g.
User
,SomeData
) - Generic types with noun names, like
Array<t>
. As a rule of thumb, your generic should be named this way if all its parameters have defaults (unfortunately TS's built-inArray
type doesn't have a default parameter, but it probably should have beenunknown
!)
- Entities/non-generic types (e.g.
-
Use
camelCase
for...- Generic types with verb names like
inferDomain<t>
. Types named this way should generally have at least one required parameter. - Parameter names, e.g.
t
inArray<t>
- Generic types with verb names like
If you don't like this, feel free to use whatever casing rules best suit your repo- it will not affect your Types or scope aliases in any way.
Why isn't my wrapper generic working?
TypeScript generic inference is notoriously finicky. General patterns for wrapping Types and definitions are outlined in the Generics docs.
If you want to write type-level logic, you need to cast.
When implementing a function with a generic return type, you will almost always need to cast in your implementation, either explicitly via as
or by using an overload.
Think of it as trading internal safety for external precision. As long as the function you're writing will be called many times externally, the overhead is justified. If not, it may not need to be generic at all- a broad return type like string
as opposed to ${prefix}.${key}
may be sufficient.
See an example
Notice in both cases, we've explicitly annotated the return type we want and used some method of casting internally to allow our implementation. This is a very common for implementing generic functions and, more generally, associating an implementation with typings TS can't infer on its own.
For anything more complex, you'll have to rely on your understanding of type manipulation to achieve the desired outcome. Tracing your way through ArkType's internal types may uncover helpful patterns, and you may even find friendly folks in our Discord who may be willing to lend a hand.
Generally speaking however, we cannot guarantee your generics will behave the way you expect.
Writing a good generic function can require understanding many complex details and edge cases- the kind of stuff our core API abstracts away.
Unfortunately, when it comes to how ArkType integrates with external generics, that is not possible.
Getting the results you want will take patience, but the DX ceiling for this kind of API is crazy high.
If we haven't scared you off by now, we're hyped to see what you build with it 🧗