简体   繁体   中英

Typescript Utility type to handle database schema defaults

I'm looking for a way to type default and virtual (aka. auto generated from other values) values for a database schema. The idea is to use an utility type to automatically convert a schema for insertion (props with defaults or generated by virtuals aren't required) and on the other side as a query result (eg. we are sure that these fields will be populated by defaults or other "virtual"-like settings so they can be flagged as NonNullable ).

So something like that if we simplify typings to a single prop:

type WithDefault<T> = T;
// Mark prop as optional
type Input<T> = T extends WithDefault<infer T> ? T | undefined : T;

The obvious issue with that is that there is no difference between Input<WithDefault> and Input. Any idea of something that could help achieve a pattern like that? Ending up with a schema like:

type User = {
  firstName: string
  lastName: string
  fullName: WithDefault<string>
}

And being able to switch back and forth to an insert-able schema to a read-able schema.

The problem - as you say - is that the types are structurally equivalent, so TS treats them the same.

You can tag it with some property with type never to distinguish between the two. The downside is that you're adding a property that needs to not exist, but you can mitigate this by using a Symbol as it is guaranteed to be unique.

Code below (TS playground link here ):

const __hasDefault = Symbol('__hasDefault');

type WithDefault<T> = T & { [__hasDefault]: never }

type User = {
  firstName: string
  lastName: string
  fullName: WithDefault<string>
}

type ConvertSchema<S extends object> = {
  [key in keyof S]: S[key] extends WithDefault<infer T> ? T | undefined : S[key];
}

type result = ConvertSchema<User>;

This gives you the following result - is that what you were looking for?

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM