Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

229
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!