programing

HOC 대응 및 TypeScript 3.2

jooyons 2023. 6. 14. 21:51
반응형

HOC 대응 및 TypeScript 3.2

TypeScript가 v3.2에서 JSX 유형 검사를 개선함에 따라 현재 HOC를 올바르게 입력하는 데 문제가 있습니다.

TypeScript 3.2용으로 다음 HOC에서 유형을 수정할 수 있는 사람이 있습니까?

import { ComponentType } from 'react';

type Props = { custom: string };
type Omit<T, K extends string> = Pick<T, Exclude<keyof T, K>>;

function hoc<P extends Props>(Component: ComponentType<P>) {
  return (props: Omit<P, keyof Props>) => {
    return <Component {...props} custom="text" />;
  }
}

TypeScript 오류:

Type '{ custom: string; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Property 'custom' does not exist on type 'IntrinsicAttributes & P & { children?: ReactNode; }'

기본적으로 이 아이디어는 "사용자 지정" 속성이 필요한 구성 요소를 HOC에 의해 자동으로 주입되므로 더 이상 필요하지 않은 구성 요소로 변환하는 것입니다.

편집: 아마도 동일한 문제일 것입니다: https://github.com/Microsoft/TypeScript/issues/28748

이것이 당신이 희망했던 답은 아닐 것입니다만, 당신은 그것의 유형을 변경함으로써 그것을 작동시킬 수 있습니다.props에 대한 내적인 역할로any그리고 그것을 넣는 것.Omit외부 함수의 반환 형식 주석을 다음과 같이 입력합니다.

function hoc<P extends Props>(Component: ComponentType<P>): ComponentType<Omit<P, keyof Props>> {
  return (props: any) => {
    return <Component {...props} custom="text" />;
  }
}

이것은 농담 테스트와 함께 Ref 전달을 지원하는 HoC입니다.

하나뿐입니다.as제가 입력 소품을 포장된 구성요소에서 사용하는 소품으로 변환하는 부분입니다. 서로 다를 수 있기 때문입니다.

참고:T생성자를 제공하는 방법에 따라 React-Native와 React JS가 다르기 때문에 임의일 수 있습니다.ReactElement의 T형 인수는 무엇입니까?무엇에 대한 관련 질문입니다.T사실은.

import { render } from '@testing-library/react-native';
import { ComponentType, forwardRef, NamedExoticComponent, PropsWithoutRef, ReactElement, Ref, RefAttributes, useEffect, useRef } from 'react';
import { Text, TextProps } from 'react-native';

/**
 * This is a simple HoC that is a noop that supports ref forwarding.
 * @param Component component to wrap
 * @param options options for the HoC building
 * @typeParam P the exposed props of the higher order component
 * @typeParam Q the props for the wrapped component
 * @typeParam T type for ref attribute of the wrapped component
 * @typeParam O options for the HoC building
 * @returns A named exotic componentwith P props that accepts a ref
 */
function hoc<P, Q, T, O = {}>(Component: ComponentType<Q>, options?: O): NamedExoticComponent<PropsWithoutRef<P> & RefAttributes<T>> {
    function wrapped(props: P, ref: Ref<T>): ReactElement<Q> {
        // the an unknown as Q here is an example, but P and Q can be different.
        const componentProps: Q = props as unknown as Q;
        return <Component {...componentProps} ref={ref} />
    }
    const displayName =
        Component.displayName || Component.name || "AnonymousComponent";
    wrapped.displayName = displayName;
    return forwardRef(wrapped);
}

describe("hoc", () => {
    it("should work with text", () => {
        const HocText = hoc<TextProps, TextProps, Text>(Text);
        const { toJSON } = render(<HocText>simple string</HocText>);
        const { toJSON: expectedToJSON } = render(<Text>simple string</Text>)
        expect(toJSON()).toStrictEqual(expectedToJSON())
    });

    it("should pass ref for text", () => {
        const callback = jest.fn();
        const HocText = hoc<TextProps, TextProps, Text>(Text);
        function MyComponent() {
            const textRef = useRef<Text>(null);
            useEffect(() => {
                callback(textRef?.current)
            }, []);
            return <HocText ref={textRef}>simple string</HocText>
        }

        const { toJSON } = render(<MyComponent />);
        const { toJSON: expectedToJSON } = render(<Text>simple string</Text>)
        expect(toJSON()).toStrictEqual(expectedToJSON())
        expect(callback).toBeCalledTimes(1);
        expect(callback.mock.calls[0][0]).toBeTruthy();
    });

    it("should work the same way with normal Text", () => {
        const callback = jest.fn();
        function MyComponent() {
            const textRef = useRef<Text>(null);
            useEffect(() => {
                callback(textRef?.current)
            }, []);
            return <Text ref={textRef}>simple string</Text>
        }

        const { toJSON } = render(<MyComponent />);
        const { toJSON: expectedToJSON } = render(<Text>simple string</Text>)
        expect(toJSON()).toStrictEqual(expectedToJSON())
        expect(callback).toBeCalledTimes(1);
        expect(callback.mock.calls[0][0]).toBeTruthy();
    });


});

언급URL : https://stackoverflow.com/questions/53556160/react-hoc-and-typescript-3-2

반응형