rhys-vdw / ts-auto-guard

Generate type guard functions from TypeScript interfaces
MIT License
501 stars 55 forks source link

Implement an "auto-cast" feature #206

Closed slevy85 closed 1 year ago

slevy85 commented 2 years ago

Hello,

Thank you very much, this library is very nice and very useful.

I have a request feature, I would like to have the possibility to also generate "cast" functions that would take in income an unknown param and apply to it the checks and transformations needed to return a correct shaped object. It would be very useful for cases like Date serialization, where JSON.stringify transform Date into string, but JSON.parse does not do the opposite.

Some code

interface Post {
 id:number
createdAt: Date
}

const postSerialized = {
  id:1,
  createdAt: "2018-01-24T11:19:30.000Z"
}

const correctPost: Post = castPost(postSerialized)

The cast functions could also take care of parsing strings to numbers or numbers to string.

The cast function could like like this :

function castPost(obj: unknown): Post | null {
  const typedObj = obj as Post
  const id = typeof typedObj.id === 'number' ? typedObj.id : Number(typedObj.id)
  const createdAt =
    typedObj.createdAt instanceof Date
      ? typedObj.createdAt
      : new Date(typedObj.createdAt)
  return { id, createdAt }
}

What do you think ?

rhys-vdw commented 2 years ago

Hello, glad you're enjoying the library! Hm. I'm not sure if I'd want a non-number value to be automatically coerced to Number() like that. It's not clear to me that would be a handy feature for most users.

slevy85 commented 2 years ago

This could be more strict or have some checks like

function castNumber(param:unknown){
  const number = Number(param)
  if(isNaN(number)){
    // fail
  }
  return number
  }

Or maybe a solution would be to only cast non-primitives like dates.

I initially saw that deepKit has this features and i found it interesting https://docs.deepkit.io/english/serialization.html#serialisation-cast.

rhys-vdw commented 1 year ago

Closing because this is not a type guard feature.