Búsqueda de sitios web

javascript - Tipo genérico 'Props' no es asignable al tipo 'IntrinsicAttributes & Props'


Soy bastante nuevo en Typescript, y estoy tratando de entender qué está pasando exactamente, y por qué. He actualizado la dependencia de TypeScript del proyecto, de la versión 4.7.4 a la más reciente 4.8.4, y estoy recibiendo errores en componentes que están usando propiedades genéricas.

Ejemplo :

export const withSomething = function <Props>(Component: FunctionComponent<Props>): FunctionComponent<Props> {
    const WithSomething = function (props: Props) {
        return <Component {...props} />
    };

    return WithSomething;
};

He eliminado cualquier lógica real del ejemplo, originalmente estaba envolviendo el componente en algún proveedor adicional. Props son genéricos. Este código funcionaba perfectamente con la versión 4.7.4 de TypeScript. Pero para la 4.8.4 estoy recibiendo los siguientes errores:

error TS2322: Type 'Props' is not assignable to type 'IntrinsicAttributes & Props'.
  Type 'Props' is not assignable to type 'IntrinsicAttributes'.
export const withSomething = function <Props>(Component: FunctionComponent<Props>): FunctionComponent<Props> {
                                       ~~~~~
This type parameter might need an `extends JSX.IntrinsicAttributes` constraint.

Ahora, tal vez no sé exactamente qué mirar, pero para mí no hay nada en el código fuente de react que obligue a que las Props de FunctionComponent extiendan JSX.IntrinsicAttributes. He pasado un par de horas intentando encontrar la causa, y por ahora no tengo idea de lo que realmente está pasando. Tampoco veo necesariamente algo en las notas de la versión de Typescript que explique esto, pero probablemente no entiendo lo suficiente de ellas.

Puedo simplemente extender JSX.IntrinsicAttributes, actualizar todos los lugares que están usando este código y probablemente funcionará, pero me gustaría saber qué está pasando y si este es el enfoque correcto. Después de leer varios temas, estoy bastante seguro de que me estoy perdiendo de algo bastante obvio.

Agradecería cualquier ayuda.

Respuesta #1

Sé que esta pregunta es un poco antigua, pero aquí están mis pensamientos.

Independientemente del hecho de que la propiedad key sea opcional en IntrinsicAttributes, sigue siendo de tipo objeto. De hecho, props siempre es de tipo objeto

Por ejemplo:

// this fails:

const func2 = (someParam : {test?: string}) => someParam.test;

const func1 = <P, >(someParam: P) => func2(someParam);

// And this passes:

const func2 = (someParam : {test?: string}) => someParam.test;

const func1 = <P extends {}>(someParam: P) => func2(someParam);

Cambiaría tu código a:

export const withSomething = function <Props extends {} /* note this change*/>(Component: FunctionComponent<Props>): FunctionComponent<Props> {
    const WithSomething = function (props: Props) {
        return <Component {...props} />
    };

    return WithSomething;
};

Respuesta #2

Técnicamente, IntrinsicAttributes solo tiene la propiedad 'key', así que puedes simplemente pasar una key al Componente y se compilará. En teoría, es una solución frágil, pero quién sabe cuándo se añadirá algo más a esa interfaz.

export const withSomething = function <Props>(Component: React.FunctionComponent<Props>): React.FunctionComponent<Props> {
    const WithSomething = function (props: Props) {
        return <Component {...props} key="ComponentWithSomething" />
    };

    return WithSomething;
};