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

145
Visualizações
Mecanografiado complejo genéricos con componentes

Estaba haciendo esta pregunta con una versión más compleja de este concepto básico
Rel: ¿Pueden los Generic JSX.Elements funcionar en Typescript?

Lo reduje a los Elementos principales:

Este es el Object A que toma parámetros de TypeA

 type TypeA = { label: string value: number } const ObjA = ({ label, value }:TypeA) => { return <div> <div>Label: {label}</div> <div>Value: {value}</div> </div> }

Este es Object B que toma parámetros de TypeB

 type TypeB = { label: string value: string bool: boolean } const ObjB = ({ label, value, bool }:TypeB) => { return <div> <div>Label: {label}</div> {bool && <div>Value: {value}</div>} </div> }

Ahora recopilo este ComponentGroup dentro de una matriz y creo un Tipo a partir de esta matriz:

 const ComponentCollection = [ ObjA, ObjB ] as const type Components = typeof ComponentCollection[number]

Luego creo un componente genérico:

 interface GenericProps<T extends Components> { Component: T title: string } const Generic = <T extends Components,>({ Component, title, ...props }:GenericProps<T>) => { return ( <div> <label>{title}</label> <Component {...props}/> </div> ) }

Por fin puedo llamar al componente genérico de la siguiente manera:

 <Generic Component={ObjA} title={'Usage A'} label={'Object A'} value={'String A'}/> <Generic Component={ObjB} title={'Usage B no Bool'} label={'Object B'} value={0}/> <Generic Component={ObjB} title={'Usage B with Bool'} label={'Object B'} value={0} bool/>

Aunque funciona muy bien en JavaScript, estropeé algo con la escritura.

Configuré un TS-Playground y un Codepen:
TS-Patio de juegos: https://tsplay.dev/WvVarW
Codepen: https://codepen.io/Cascade8/pen/eYezGVV

Meta:

  1. Convierta este código anterior en código TypeScript correcto
  2. Compile sin ningún TS-Errors o /@ts-ignore
  3. Haga que IntelliSense funcione, de modo que si escribe <Generic Component={ObjA} ... muestra los atributos de tipo disponibles para este Objeto. En este caso: label={string: } value={string: }

Lo que no quiero:

  1. El uso de clases o la sintaxis de función anterior como nuestro EsLint requiere que usemos una función de flecha si es posible.
  2. Pasar los objetos como un niño.
    Sé que esto funciona, pero no es la solución preferida ya que el Proyecto principal tiene muchos grupos como este que se renderizan de esta manera.
    ¿Y por qué no debería funcionar algo en TypeScript que funciona de manera muy simple en JavaScript?
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Siguiendo la forma en que ha construido sus tipos, puede hacerlo usando la definición de su genérico dentro de GenericProps

(Tenga en cuenta que he incluido los accesorios en un nuevo props de accesorios, ya que esto debería evitar colisiones de nombres en caso de que tenga colisiones de nombres)

 import React from 'React' type TypeA = { label: string value: number } const ObjA = ({ label, value }:TypeA) => { return <div> <label>{label}</label> <label>{value}</label> </div> } type TypeB = { label: string value: string bool: boolean } const ObjB = ({ label, value, bool }:TypeB) => { return <div> <label>{label}</label> {bool && <label>{value}</label>} </div> } type Components = typeof ObjA | typeof ObjB; interface GenericProps<T extends (...args: any) => any> { Component: T title: string props: Parameters<T>[0] } const Generic = <T extends Components,>({ Component, title, props }:GenericProps<T>) => { return ( <div> <label>{title}</label> <Component {...props as any}/> </div> ) } const Usage = () => { return <Generic Component={ObjA} title={'Usage'} props={{label: 'ObjectA'}}/> } export default Generic
over 4 years ago · Santiago Trujillo Relatório

0

Es posible prescindir de cualquier tipo de aserciones de tipo. Considere este ejemplo:

 import React, { FC, } from 'react' type Type = { label: string; value: string | number } type TypeA = { label: string value: number } type FixSubtyping<T> = Omit<T, 'title'> const ObjA = ({ label, value }: FixSubtyping<TypeA>) => { return <div> <label>{label}</label> <label>{value}</label> </div> } type TypeB = { label: string value: string bool: boolean } const ObjB = ({ label, value, bool }: FixSubtyping<TypeB>) => { return <div> <label>{label}</label> {bool && <label>{value}</label>} </div> } type Props<T> = T & { title: string } const withTitle = <T extends Type>(Component: FC<FixSubtyping<Props<T>>>) => ({ title, ...props }: Props<T>) => ( <div> <label>{title}</label> <Component {...props} /> </div> ) const GenericA = withTitle(ObjA) const GenericB = withTitle(ObjB) const jsxA = <GenericA title={'Usage'} label={'A'} value={42} /> // // ok const jsxB = <GenericB title={'Usage'} label={'A'} value={'str'} bool={true} /> // // ok

Patio de recreo

Este error ocurre porque props se infieren como Omit Omit<T,'title'> , por lo que debemos asegurarle a TS que props de componentes son compatibles con Omit<T,'title'>

Sin embargo, existe un inconveniente: debe actualizar el tipo de accesorios en otros componentes. Si no es una opción, creo que el mejor enfoque sería sobrecargar su función Generic :

 import React, { FC, } from 'react' type TypeA = { label: string value: number } type FixSubtyping<T> = Omit<T, 'title'> const ObjA = ({ label, value }: TypeA) => { return <div> <label>{label}</label> <label>{value}</label> </div> } type TypeB = { label: string value: string bool: boolean } const ObjB = ({ label, value, bool }: TypeB) => { return <div> <label>{label}</label> {bool && <label>{value}</label>} </div> } type Props<T> = T & { Component: FC<T>, title: string } function Generic<T,>(props: Props<T>): JSX.Element function Generic({ Component, title, ...props }: Props<unknown>) { return ( <div> <label>{title}</label> <Component {...props} /> </div> ) } const jsxA = <Generic Component={ObjA} title={'Usage'} label={'A'} value={42} /> // // ok const jsxB = <Generic Component={ObjB} title={'Usage'} label={'A'} value={'str'} bool={true} /> // // ok

Patio de recreo

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