Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

232
Vistas
Unión de dos objetos de mecanografiado: problema al hacer que mecanografiado piense que es el otro tipo

Encontré un problema realmente extraño y no estoy seguro de si el problema está relacionado con tipos mal escritos o es algo raro en el mecanografiado.

Así que tengo este tipo de accesorios:

 type SelectAnswersProps = ( | { onChange: Dispatch<SetStateAction<MultiSelectAnswerOptionsType | null>>; value: MultiSelectAnswerOptionsType; isMultiSelect: true; } | { onChange: Dispatch<SetStateAction<SelectAnswerOptionsType | null>>; value: SelectAnswerOptionsType; isMultiSelect: false; } ) & { displayMode?: SelectAnswerOptionsType['displayMode']; disabled?: boolean; };

Y luego estoy tratando de forzar el mecanografiado para leer qué tipo se pasa al método onChange .

 if (isMultiSelect) { onChange({ answers, isHeadless, }); } else { onChange({ answers, displayMode, }); }

Entonces, el primer onChange es correcto ya que muestra su tipo como onChange: (value: SetStateAction<MultiSelectAnswerOptionsType>) => void pero el segundo espero que sea como en los tipos especificados en props con isMultiSelect siendo false pero en cambio tipo de El segundo onChange es el siguiente: onChange: (value: SetStateAction<MultiSelectAnswerOptionsType> & SetStateAction<SelectAnswerOptionsType>) => void , por lo que es una especie de combinación de ambos aunque, según los tipos de accesorios, diría que es uno u otro.

Creo que he hecho algo tonto aquí. Realmente aprecio toda su ayuda.

Gracias

about 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Ha definido que los props sean (simplificados para facilitar la lectura) :

 props: { onChange: MultiSelectDispatcher, ... } | { onChange: SelectDispatcher, ... }

Eso significa que los props solo pueden ser uno u otro, y Typescript no sabe cuál es, y lo infiere del uso:

 if( isMultiSelect ){ onChange({ answers, isHeadless }); // <-- TS thinks: probably the "MultiSelect" one } else { onChange({ answers, displayMode }); // <-- TS already decided "MultiSelect" earlier }

Por lo tanto, Typescript decide qué tipo es probablemente el objeto de props completo en algún momento, y se apega a esa decisión a partir de ese momento.

Use un tipo de guardia (tal vez)

Como solución, es posible que pueda usar protectores de tipo (tal vez no sea tan fácil, consulte el "Pero ..." a continuación) , como:

 const guardMultiSelectProps = ( theProps: unknown ): theProps is MultiSelectProps => { return theProps.isMultiSelect; } if( guardMultiSelectProps( theProps ) ){ onChange({ answers, isHeadless }); // <-- TS thiks: probably the "MultiSelect" one } else { onChange({ answers, displayMode }); // <-- TS already decided "MultiSelect" earlier }

Pero también Typescript podría haber inferido el tipo de accesorios incluso antes, o "repentinamente" lo hará si realiza algunos cambios en su código más adelante.

Definir el tipo de onChange (si es posible)

Sugiero, si es posible, no definir dos alternativas para el objeto props , sino definir solo un tipo para props , con dos controladores onChange alternativos. (Los accesorios de React deberían ser consistentes de todos modos)

P.ej:

 props: { onChange: MultiSelectDispatcher | SelectDispatcher, ... }

Y también use un protector de tipo, como:

 // Note: This type guard works, but is not inherently type safe. const guardMultiSelectOnChange = ( onChange: unknown, multiSelect: boolean ): onChange is MultiSelectDispatcher => { return multiSelect; } if( guardMultiSelectOnChange( onChange, isMultiSelect )) { onChange({ answers, isHeadless }); } else { onChange({ answers, displayMode }); }

Todavía problemas...

Mi último tipo de guardia guardMultiSelectOnChange hace que otro problema sea obvio:

Siempre asumimos que la función onChange es la correcta si isMultiSelect es una u otra. Pero nada impide que alguien pase isMultiSelect: false y MultiSelectDispatcher .

Sería mejor proteger la firma de la función en sí, en lugar de simplemente indicar que onChange is MultiSelectDispatcher si alguna otra propiedad ( isMultiSelect ) tiene algún valor.

Pero supongo que será una refactorización algo mayor, fuera del alcance de esta pregunta.

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda