Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

828
Visualizações
Vue 3 Typescript props validation at both compile and runtime

My team is building a Vue 3 component library. As the project goes larger in scale, we refactored it with typescript to get a better developing experience.

But here's the thing - there are teams using our lib in different environments, with or without typescript and bundler, which means for almost every component we need to validate prop types both in compile-time and runtime.

props: {
  someProp: {
    type: String as PropType<'enum1' | 'enum2' | 'enum3'>,
    validator: (v: string) => {
      return ['enum1', 'enum2', 'enum3'].includes(v)
    }
  }
}

The code runs well. Teams using typescript are happy - they got their code completion and can spot potential errors ahead of time. Teams using javascript are happy - they can discover any type-related errors at runtime thanks to the validator. But we are not happy, since the code is duplicated. Technically <'enum1' | ...> is a type def and ['enum1', ...] is an array, they are not the same thing - but we literally write the same string multiple times.

Is there any way to implement something that can define a prop with PropType and validator without having to reeeeeeepeat myself?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Well, currently I'm doing something like this:

export const buildProp = <
  T = any,
  R extends boolean = boolean,
  D extends T = T
>({
  type?: any,
  /* all the values allowed for this prop */
  values?: readonly T[],
  required?: R,
  /* if a prop is required, it shouldn't default to any value */
  /* if a prop has a default value, it shouldn't be marked as required */
  defaultValue?: R extends true
    ? never
    : D extends Record<string, unknown> | Array<any>
      ? () => D
      : D,
  /* any other validations */
  validator?: (val: any) => boolean
} = {}) => {
  return {
    type: type as PropType<T | never>,
    required: !!required,
    default: defaultValue,
    validator: (val: any) => {
      let valid = false

      // we see if the prop value passed in is in the union
      // or is the defaultValue
      if (values) {
        valid =|| [...values, defaultValue].includes(val)
      }
      if (validator) {
        valid =|| validator(val)
      }

      return valid
    }
  }
}

As a result,

someProp: buildProp({
  type: String,
  values: ['enum1', 'enum2', 'enum3']
})

will produce

someProp: {
  type: String as PropType<'enum1' | 'enum2' | 'enum3'>,
  validator: (val) => {
    return ['enum1', 'enum2', 'enum3'].includes(val)
  }
}

if (props.someProp === 'illegalValue') {
  // ERR: will always return false since type "'enum1' | 'enum2' | 'enum3'" has no overlap with "illegalValue"
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda