Definitelytyped: react-router :`withRouter`๊ฐ€ 3.6.2๋ถ€ํ„ฐ`ComponentType`์œผ๋กœ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2019๋…„ 09์›” 10์ผ  ยท  10์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: DefinitelyTyped/DefinitelyTyped

์ด๊ฒƒ์€ 3.5.2์—์„œ ์ž‘๋™ํ–ˆ์ง€๋งŒ 3.6.2์—์„œ๋Š” ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

strict ๋ชจ๋“œ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ดํ•‘์ด๋‚˜ TypeScript์˜ ๋ฒ„๊ทธ์ž…๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์— ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค : https://github.com/DefinitelyTyped/DefinitelyTyped/commit/f036856dfc9a7fd140f378402c102206738ec0a4.

import * as React from 'react';

// Copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/5db94ca7fd3570dc23588b404d7bb669a7886a8a/types/react-router/index.d.ts#L146
declare function withRouter<P, C extends React.ComponentType<P>>(
    component: C & React.ComponentType<P>,
): unknown;

declare const Component: React.ComponentType<{}>;
/*
Argument of type 'ComponentType<{}>' is not assignable to parameter of type 'ComponentClass<{}, any> | (ComponentClass<{}, any> & FunctionComponent<{}>)'.
  Type 'FunctionComponent<{}>' is not assignable to type 'ComponentClass<{}, any> | (ComponentClass<{}, any> & FunctionComponent<{}>)'.
    Type 'FunctionComponent<{}>' is not assignable to type 'ComponentClass<{}, any> & FunctionComponent<{}>'.
      Type 'FunctionComponent<{}>' is not assignable to type 'ComponentClass<{}, any>'.
        Type 'FunctionComponent<{}>' provides no match for the signature 'new (props: {}, context?: any): Component<{}, any, any>'.
*/
withRouter(Component);

๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋Œ€์‹  ํ’€ ์š”์ฒญ์„ํ•˜์‹ญ์‹œ์˜ค.

  • [x] @types/xxxx ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • [x] ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „์˜ tsc๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. https://www.npmjs.com/package/typescript
  • [x] StackOverflow์— ๋ถ€์ ์ ˆํ•œ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. (๊ทธ๊ณณ์—์„œ ์ ์ ˆํ•œ ์งˆ๋ฌธ์„ํ•˜์‹ญ์‹œ์˜ค).
  • [x] [Mention] (https://github.com/blog/821-mention-somebody-they-re-notified) ์ž‘์„ฑ์ž ( Definitions by: ์˜ index.d.ts ) ์‘์ฐฝ ์„ฑ๊ฐ€.

    • ์ž‘์„ฑ์ž : @ sergey-buturlakin @ mrk21 @ vasek17 @ngbrown @awendland @KostyaEsmukov @johnnyreilly @LKay @DovydasNavickas @ @grmiade @DaIgeb @egorshulga @rraina @ pret-a-porter @ t49tran @ 8enSmith @wezleytsai @ eps1lon

์ €์ž๋ฅผ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด ์ˆ˜์ • ํ›„์—๋„ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 Argument of type '({ myProp, history }: RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }) => Element' is not assignable to parameter of type 'ComponentType<RouteComponentProps<{}, StaticContext, any>>'.
  Type '({ myProp, history }: RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }) => Element' is not assignable to type 'FunctionComponent<RouteComponentProps<{}, StaticContext, any>>'.
    Types of parameters '__0' and 'props' are incompatible.
      Type 'PropsWithChildren<RouteComponentProps<{}, StaticContext, any>>' is not assignable to type 'RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }'.
        Property 'myProp' is missing in type 'RouteComponentProps<{}, StaticContext, any> & { children?: ReactNode; }' but required in type '{ myProp: boolean; }'.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ ๋œ ๊ตฌ์„ฑ ์š”์†Œ

import { RouteComponentProps, withRouter } from "react-router-dom";

interface Props extends RouteComponentProps {
  myProp: boolean;
}

const Component = ({ myProp, match }: Props) => null

export default withRouter(Component);

๋‚˜๋Š” ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋‹ค

typescript: 3.6.3
@types/react-router: 5.0.4

๋ชจ๋“  10 ๋Œ“๊ธ€

๋‚˜๋Š” ์ด๊ฒƒ์„ ํŒŒํ—ค์น  ์‹œ๊ฐ„์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ComponentType ์‚ฌ์šฉ์„ ์ œ๊ฑฐํ•˜๊ณ  ref ๋ฐ children ๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋ช…์‹œ ์  props์™€ ํ•จ๊ป˜ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ComponentType ๋Š” ๋…ธ์กฐ๋กœ ์ธํ•ด ํ•ญ์ƒ ์•ฝ๊ฐ„ ๋ฌธ์ œ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค๋ฅธ hoc์™€ ๋งค์šฐ ํฐ ๊ฒฐํ•ฉ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„์„œ๊ด€ ์†Œ๋น„์ž๋Š” ์–ด์ฐจํ”ผ ์ •์ ์„ ๋งŒ์ ธ์„œ๋Š” ์•ˆ๋˜๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ์ •๋ณด๋ฅผ ์žƒ์–ด ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. react-router repo (https://github.com/ReactTraining/react-router/issues/6906)์— ์ด๋ฏธ๋ณด๊ณ ๋˜์—ˆ์ง€๋งŒ ์—ฌ๊ธฐ๋กœ ๋ฆฌ๋””๋ ‰์…˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์ˆ˜์ • ํ›„์—๋„ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 Argument of type '({ myProp, history }: RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }) => Element' is not assignable to parameter of type 'ComponentType<RouteComponentProps<{}, StaticContext, any>>'.
  Type '({ myProp, history }: RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }) => Element' is not assignable to type 'FunctionComponent<RouteComponentProps<{}, StaticContext, any>>'.
    Types of parameters '__0' and 'props' are incompatible.
      Type 'PropsWithChildren<RouteComponentProps<{}, StaticContext, any>>' is not assignable to type 'RouteComponentProps<{}, StaticContext, any> & { myProp: boolean; }'.
        Property 'myProp' is missing in type 'RouteComponentProps<{}, StaticContext, any> & { children?: ReactNode; }' but required in type '{ myProp: boolean; }'.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ ๋œ ๊ตฌ์„ฑ ์š”์†Œ

import { RouteComponentProps, withRouter } from "react-router-dom";

interface Props extends RouteComponentProps {
  myProp: boolean;
}

const Component = ({ myProp, match }: Props) => null

export default withRouter(Component);

๋‚˜๋Š” ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋‹ค

typescript: 3.6.3
@types/react-router: 5.0.4

@ karol-majewski ์ €๋Š” TS 3.6.3์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ตœ์‹  ๋ฒ„์ „ @types/react-router: 5.0.4 ์ด ์ค‘๋‹จ๋˜๊ณ  ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

export function withRouter<P extends RouteComponentProps<any>, C extends React.ComponentType<P>>(
  component: C & React.ComponentType<P>,
): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;

์ €๋Š” ๋ชจ๋‘๊ฐ€ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์—ด๋„๋ก ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ ๋น„๊ณต๊ฐœ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ๋Œ“๊ธ€์„ ๋‹ฌ๋ฉด ์•Œ๋ฆผ์„๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด์ œ typescript ํ”Œ๋ ˆ์ด ๊ทธ๋ผ์šด๋“œ์—์„œ ts ๋ฒ„์ „ + ๊ตฌ์„ฑ์„ ๊ตฌ์„ฑ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์œ ํ˜• ์ •์˜๋ฅผ ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ด์Šˆ์— ๋งํฌ๋ฅผ ํฌํ•จํ•˜๋ฉด ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋งŽ์€ ๋„์›€์ด๋ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :

์ด๊ฒƒ์€ strictFunctionTypes ๋กœ๋งŒ ๋˜์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉฐ ๋งˆ์Œ์— ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์ด ์ž˜๋˜๋Š”์ง€ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@sandersn ์ˆ˜์ • ์‚ฌํ•ญ ์„ ๋˜ ๋Œ๋ฆฐ ํ›„ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

IIRC, @ eps1lon ์€ ์ด๊ฒƒ์ด TypeScript ๋ฒ„๊ทธ ๋•Œ๋ฌธ https://github.com/microsoft/TypeScript/issues/33490

์ˆ˜์ • ์‚ฌํ•ญ : https://github.com/microsoft/TypeScript/pull/34607.

์•ผ๊ฐ„ ๋ฒ„์ „์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋†€์ดํ„ฐ ๋งํฌ

ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ๋Š” ์‹œ๊ฐ„ ๋‚ญ๋น„์ž…๋‹ˆ๋‹ค. ์ €๋Š”์ด ๋ฉ์ฒญํ•œ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ์‹œ๊ฐ„์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‚ถ์„ ํŽธํ•˜๊ฒŒํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์กŒ๋‹ค๋ฉด ๋ถ„๋ช…ํžˆ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ  ์˜ค๋ฅ˜์™€ ๋ฒ„๊ทธ๋กœ โ€‹โ€‹๊ฐ€๋“ ์ฐจ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” TS 3.7์—์„œ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ์‡„.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰