sinclairzx81 / typebox

Json Schema Type Builder with Static Type Resolution for TypeScript
Other
4.98k stars 157 forks source link

Read other properties value #507

Closed mlazuardy closed 1 year ago

mlazuardy commented 1 year ago

is there anyway to read other properties value within especially when using Typesystem? in this case i want to create validation for password confirmation which the field need to read the password field value

sinclairzx81 commented 1 year ago

@mlazuardy Hi,

You can pass options for the custom type into the TypeSystem.Type method. These are passed as generic arguments. The first argument is the inference type (i.e. Credential), the second argument is any options used to when validating the type (i.e. CredentialOptions)

The following example implements a Credential type that passes both inference and options types.

TypeScript Link Here

import { TypeSystem } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'

// -------------------------------------------------------
// Credential Type
// -------------------------------------------------------
export interface CredentialOptions {
  useConfirm: boolean
}
export interface Credential {
  password: string
  confirm?: string
}
const Credential = TypeSystem.Type<Credential, CredentialOptions>('Credential', (options, value) => {
  if(!(typeof value === 'object' && value !== null)) return false 
  if(!('password' in value && typeof value.password === 'string')) return false
  if(options.useConfirm) {
    if(!('confirm' in value && typeof value.confirm === 'string')) return false
    // tip: you should use timing safe equals to perform all credential checks. see link below
    //
    // https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b
    //
    if(!(value.password === value.confirm)) return false // don't use '===' !
  }
  return true
})

// -------------------------------------------------------
// Usage
// -------------------------------------------------------
import { Value } from '@sinclair/typebox/value'

const Form = Type.Object({
  credential: Credential({ useConfirm: true })
})
const R1 = Value.Check(Form, {
  credential: {
    password: 'password',
    confirm: 'password'
  }
})
const R2 = Value.Check(Form, {
  credential: {
    password: 'password',
    confirm: 'password2'
  }
})

console.log(R1, R2) // true false

Hope this helps S

sinclairzx81 commented 1 year ago

@mlazuardy Hi, might close off this issue.

If you have any follow up questions on the implementation above, or need to additional functionality from custom types, feel free to ping a reply on this thread.

All the best! S

mlazuardy commented 1 year ago

@sinclairzx81 thank you! i think i have planed to use that technique but what i mean is accessing other properties value on the same level / child props within Type.Object as we usually use Type.Object as a form validation