반응형
Typescript 일반 JSX 인수와 함께 React forwardRef 사용
다음과 같은 유형의 리액트 구성요소를 사용할 경우 리액트의 새로운 API로 포장하려면 어떻게 해야 합니까?
type Props<T> = {
forwardedRef?: Ref<HTMLInputElement>
...
}
class GenericComponent<T> extends Component<Props<T>> {
...
}
const ComponentWithRef = forwardRef<HTMLInputElement, Props<T>>((props, ref) => (
<StringInput<T> {...props} forwardedRef={ref} />
))
위의 접근법은 제네릭을 정의할 방법이 없다.
따라서, 질문을 좀 더 넓히기 위해, 이것은 실제로 더 높은 차수의 함수에서 제네릭 타입을 보존하는 것에 대한 질문이다. 의 다음 사용법은 체크를 적절히 입력합니다(에서)
const SelectWithRef = forwardRef(<Option extends string>(props: Props<Option>, ref?: Ref<HTMLSelectElement>) =>
<Select<Option> {...props} forwardedRef={ref} />);
그러나 제네릭은 제네릭으로 남아있지 않고 즉시 로 해결된다. 이와 같이, 다음은 체크를 타이핑하지 않는다
const onChange: (value: 'one' | 'two') => void = (value) => console.log(value);
<SelectWithRef<'one' | 'two'>
^^^^^^^^^^^^^^^ [ts] Expected 0 type arguments, but got 1
value="a"
options={['one', 'two']}
onChange={onChange}
^^^^^^^^^^ [ts] Type 'string' is not assignable to type '"one" | "two"'
/>
관련 문제는 에서 추적합니다.
다음과 같은 해결책이 있다고 생각합니다:
type Props<T> = {
ref?: MutableRefObject<HTMLDivElement | null>;
someProp: string;
testType: T;
}
const TestComponent: <T extends any>(props: Props<T>) => ReactNode = (() => {
// eslint-disable-next-line react/display-name
return forwardRef(({someProp, testType}, ref: ForwardedRef<HTMLDivElement>) => {
console.log(someProp, testType);
return <div ref={ref}>testasd</div>;
});
})();
그 다음:
type TestType = {
name: string;
};
const SomePage: FC = () => {
const someRef = useRef<HTMLDivElement | null>(null);
return (
<div>
<TestComponent<TestType> someProp='OK' ref={someRef} testType={{name: 'test'}}/>
</div>
);
};
이것은 오류 없이 컴파일된다.
의 유형이 정확하게 추론되다
다음에 오류가 발생합니다:
<TestComponent<TestType> someProp='ERROR' ref={someRef} testType={'test'}/>
Type 'string' is not assignable to type 'TestType'.ts(2322)
예상되는 바입니다.
반응형
'개발하자' 카테고리의 다른 글
주피터 노트북 디스플레이 로깅을 전환하는 방법 (0) | 2023.11.10 |
---|---|
테라폼에서 트리거 임계값과 메트릭_트리거 임계값의 차이 (1) | 2023.11.09 |
FastApi에서 Asyncio 하위 프로세스를 실행하면 구현되지 않은 오류가 발생함 (0) | 2023.11.08 |
socket.io 을 fastapi 앱에 마운트하고 연결된 모든 클라이언트에 브로드캐스트를 전송하는 방법 (0) | 2023.11.07 |
"수출"을 패키지로 어떻게 사용할 수 있나요.json은 nested submodules와 TypeScript? (0) | 2023.11.07 |