Typescript: Async user-defined typeguards

User-defined typeguards are a handy tool for covering any shortcomings in automatic type inferring in Typescript. Sadly, async typeguards are currently not supported out of the box.

Until it gets added to the engine, a straightforward workaround is to return unchanged input data with manually annotated types from the typeguard function.

For example, when validating unknown input against a Yup schema:

export async function validateWithSchema<T, K>(data: T, schema: yup.Schema<K>) {
  // `schema.validate()` will throw on invalid input
  await schema.validate(data);
  return (data as unknown) as K;
}
const typedData = await validateWithSchema(unknownInput, schema);

From there on, typedData will have full type coverage from the schema definition, no manual interface writing necessary.