@types/xxxx
ν¨ν€μ§λ₯Ό μ¬μ©ν΄ 보μλλ° λ¬Έμ κ° λ°μνμ΅λλ€.Definitions by:
in index.d.ts
) λλ΅νλ€.μ¬λ³΄μΈμ! λ°©κΈ 5.0.16
μ
λ°μ΄νΈνλλ° κΈ°μ‘΄ νλ‘μ νΈμμ μ΄λ¬ν μ μ
λ ₯μ μ¬μ©νλ λ° λ¬Έμ κ° μ¦μ λ°μνμ΅λλ€. λ€μμ λͺ κ°μ§ κ΄λ ¨ λ²μ λ²νΈμ
λλ€.
@types/react-redux: ^5.0.16,
typescript: ^2.8.x,
react-redux: ^5.0.5,
λ€μμ μ»΄νμΌν΄μΌ νλ€κ³ μκ°νλ μ½λμ
λλ€( 5.0.16
μ΄μ μ μ»΄νμΌλμκ³ λ²μ μ λ€μ 5.0.15
μ€μ νλ©΄ λ€μ μ»΄νμΌλ¨).
// components/exampleComponent.ts
import React = require('react')
import { IState, IDateRange, ReportType } from '../../types/index'
export interface IExampleProps {
label?: string
dateRange: IDateRange
onDateRangeChange: (value: IDateRange) => void
}
export class ExampleComponent extends React.Component<IExampleProps> {
// implementation
}
// containers/exampleComponent.ts
import { connect } from 'react-redux'
import { IState, IDateRange, ReportType } from '../../types/index'
interface IPropsFromState {
dateRange: IDateRange
}
interface IPropsFromParent {
reportType: ReportType
}
const mapStateToProps = (state: IState, props: IPropsFromParent): IPropsFromState => {
const config = state.reporting.reportConfigs[props.reportType]
return {
dateRange: config ? config.dateRange : null,
}
}
const connector = connect<IPropsFromState, null, IPropsFromParent>(
mapStateToProps,
)
export const ExampleContainer = connector(ExampleComponent) // <-- this does not compile
νμλΌλ©΄ μ΄λ° μ©κΈ°λ₯Ό κ³μ μ¬μ©νκ² μ§λ§,
<ExampleContainer reportType={ReportType.USERS_CREATED} />
κ·Έλ¬λ μ¬μ©νμ¬μ΄ μ½λμ μ΅μ @types/react-redux
μμ 5.0.16
μμμ νμ΄ν λΌμ΄ν° 2.8.1
λ΄κ° λμ λ€μκ³Ό κ°μ μ€λ₯λ₯Ό :
[ts]
Argument of type 'typeof ExampleComponent' is not assignable to parameter of type 'ComponentType<IPropsFromState & DispatchProp<any> & IPropsFromParent>'.
Type 'typeof ExampleComponent' is not assignable to type 'StatelessComponent<IPropsFromState & DispatchProp<any> & IPropsFromParent>'.
Type 'typeof ExampleComponent' provides no match for the signature '(props: IPropsFromState & DispatchProp<any> & IPropsFromParent & { children?: ReactNode; }, context?: any): ReactElement<any>'.
5.0.16
λμ
λ λ³κ²½ μ¬νμ κ²μ¬νλ©΄ connector
μ νμ΄ InferableComponentEnhancerWithProps<IPropsFromState & IPropsFromParent, IPropsFromParent>
μ΄λ―λ‘ μ ν μμ€ν
μ΄ μλͺ»λ κ²μ²λΌ λκ»΄μ§λλ€. μ΄λ 첫 λ²μ§Έ μΈμκ° IPropsFromState & IPropsFromParent
μ νμΌ κ²μΌλ‘ μμνλ€λ κ²μ μλ―Έν©λλ€ reportType
μμ±μ΄ μμ΅λλ€.
μλ₯Ό λ€μ΄ λ€μκ³Ό κ°μ΄ μμ±ν©λλ€.
const f = <P extends IPropsFromParent & IPropsFromState>(component: Component<P>) => { /**/ }
const g = <P extends IPropsFromParent & IPropsFromState>(props: P) => { /**/ }
const record: IExampleProps = null
f(ExampleComponent)
g(record)
μ΄λ¬ν μ΅μνμ μλ μ€ν¨ν©λλ€. 첫 λ²μ§Έλ μμ μ½λμ κ°μ μ΄μ λ‘ μ€ν¨νκ³ λμΌν λΆν¬λͺ
ν μ€λ₯ λ©μμ§κ° νμλ©λλ€. λ λ²μ§Έλ λΆλͺ
ν IExampleProps
reportType: ReportType
μμ±μ΄ μμΌλ―λ‘ IExampleProps
λ₯Ό P
ν λΉν μ μκΈ° λλ¬Έμ μ€ν¨ν©λλ€. reportType
κ° μμ΅λλ€. λλ μ΄κ²μ΄ λ΄λΆμ μΌλ‘ 첫 λ²μ§Έ μμ κ° μ€ν¨νκ² λ§λλ μμΈμ΄λΌκ³ μκ°ν©λλ€.
5.0.16
컨ν
μ΄λκ° λνλ κ΅¬μ± μμμ μΈν°νμ΄μ€μ μ μμ±μ μΆκ°ν μ μλ κ²μ²λΌ 보μ
λκΉ? μ΄κ²μ λ΄κ° μ½λλ₯Όλ³΄κ³ μλ κ²μ
λλ€.
νμν μμ±λ§ κΈ°μ€μΌλ‘ κ΅¬μ± μμλ₯Ό μ μν λ€μ μ μΈν°νμ΄μ€λ₯Ό μ μνκ³ redux μ μ₯μλ₯Ό ν΅ν΄ κ΅¬μ± μμμ μμ±μ μ 곡νλ HOCλ‘ ν΄λΉ κ΅¬μ± μμλ₯Ό νμ₯νλ κ²μ΄ μΌλ°μ μΈ μν¬νλ‘μ μΌλΆμ
λλ€. μ΄λ€ κ²½μ°μλ μ μΈν°νμ΄μ€κ° λνλ κ΅¬μ± μμ μΈν°νμ΄μ€μ νμ μ§ν©μ΄μ§λ§ λ€λ₯Έ κ²½μ°μλ κ·Έλ μ§ μμ μ μμ΅λλ€. μμ κ²½μ° μ μΈν°νμ΄μ€μλ νΈμΆμκ° μ¬μ©νμ§λ§ λνλ κ΅¬μ± μμλ λ³Ό μ μλ μΆκ° μμ± reportType
μ΄ μμ΅λλ€.
μ΄ λ³κ²½μΌλ‘ μΈν΄ μμλ κΈ°μ μ λ λ€λ₯Έ μκ° μμ΅λλ€.
λ κ°μ κ°λ¨ν κ΅¬μ± μμκ° μλ€κ³ κ°μ ν©λλ€.
class NameDateComponent extends React.PureComponent<{ name: string, date: string}> {}
class DateOnlyComponent extends React.PureComponent<{ date: string }> {}
name
μμ±μ λν΄ μ ν μ νμ μμ΄ μ΄λ¬ν κ΅¬μ± μμμ λν΄ date
λ₯Ό μ 곡νλ HOCλ₯Ό ꡬμΆνκ³ μΆμ΅λλ€. μλ₯Ό λ€μ΄, λ΄κ° ν μμλμ΄ λ°©λ²μνλ NameProviderκ³Ό DateProviderνκ³ ,μ΄μ²λΌ κ·Έλ€μ κ΅¬μ± : NameProvider(DateProvider(BaseComponent))
λλμ΄ κ°μ DateProvider(NameProvider(BaseComponent))
λλ μΌλ°μ μΌλ‘ μ μ
λ ₯ κ΅¬μ± μμμ ν¨κ» ν μ μμ΄, λκ° TOwnProps
λ₯Ό μ§μ ν΄μΌ νκΈ° λλ¬Έμ μΈνΈμκ° νμν©λλ€.
interface IWithDate {
date: string
}
// ComponenProps defines a component interface that includes IWithDate
// NewAPI defines a new interface that excludes IWithDate
// so the types represent only what will change in the given component, without needing to know the rest of the interface
function DateProvider <ComponentProps extends IWithDate, NewAPI extends Minus<ComponentProps, IWithDate>> (Base: CompositeComponent<ComponentProps>) {
const enhancer = connect<ComponentProps, null, NewAPI>(
(_state: IState, props: NewAPI): ComponentProps => {
// because of the 'never' type,
// typescript doesn't think NewAPI & IWithProps == ComponentProps
// so we have to coerce this (but you and I can see that the above holds)
const newProps: any = Object.assign({
date: '2017-01-01'
}, props)
return newProps as ComponentProps
},
null
)
return enhancer(Base) // <-- after 5.0.16 this line does not compile
}
μ΄ μλ‘μ΄ μΈν°νμ΄μ€ λΆκ°μ§λ‘ μ κ΅¬μ± μμ μΈνΈμλ λ€μκ³Ό κ°μ΄ μ¬μ©λ©λλ€.
const NameOnly = DateProvider(NameDateComponent)
const Nothing = DateProvider(DateOnlyComponent)
.
.
.
<Nothing />
<NameOnly name='Bob' />
<NameDateComponent name='Bob' date='2017-01-01' />
λ°λΌμ DateProvider
HOCλ ν΄λΉ κ΅¬μ± μμμ μΈν°νμ΄μ€λ₯Ό μμ ν μΈμνμ§ μκ³ λ κ΅¬μ± μμλ₯Ό 보κ°ν μ μμ΅λλ€. μ£Όμ΄μ§ μ»΄ν¬λνΈκ° μ 곡νλ propsλ₯Ό λ°μλ€μΌ μ μλ€λ κ²λ§ μλ©΄ λ©λλ€.
5.0.16
νλ©΄ λ μ΄μ μλνμ§ μμΌλ©° λμ λ€μ μ€λ₯ λ©μμ§κ° νμλ©λλ€.
[ts]
Argument of type 'CompositeComponent<ComponentProps>' is not assignable to parameter of type 'ComponentType<ComponentProps & NewAPI>'.
Type 'ComponentClass<ComponentProps>' is not assignable to type 'ComponentType<ComponentProps & NewAPI>'.
Type 'ComponentClass<ComponentProps>' is not assignable to type 'StatelessComponent<ComponentProps & NewAPI>'.
Types of property 'propTypes' are incompatible.
Type 'ValidationMap<ComponentProps>' is not assignable to type 'ValidationMap<ComponentProps & NewAPI>'.
Type 'keyof ComponentProps | keyof NewAPI' is not assignable to type 'keyof ComponentProps'.
Type 'keyof NewAPI' is not assignable to type 'keyof ComponentProps'.
Type 'keyof NewAPI' is not assignable to type '"date"'.
λλ€κ° λ€μμ λ°κ²¬νμ΅λλ€.
interface IWithDate {
date: string
}
interface IComponentProps {
name: string
date: string
}
// I've torn out the internals of the DateProvider above
const connect1 = <T extends IWithDate, U extends Omit<T, keyof IWithDate>>(base: CompositeComponent<T>) => {
const enhancer: InferableComponentEnhancerWithProps<T & U, U> = () => null
return enhancer(base) // <-- this is a compile error
}
const connect2 = <T extends IWithDate, U extends Omit<T, keyof IWithDate>>() => {
const enhancer: InferableComponentEnhancerWithProps<T & U, U> = () => null
return enhancer
}
const enhancer = connect2<IComponentProps, Omit<IComponentProps, keyof IWithDate>>()
const container = enhancer(NameDateComponent) // <-- this is not a compile error
컀λ₯ν°λ₯Ό λͺ μμ μΌλ‘ μ λ ₯νλ©΄ λͺ¨λ κ²μ΄ μλν©λκΉ?
κ·Έκ² λ€μΌ! μ½μ΄μ£Όμ
μ κ°μ¬ν©λλ€ ;) μ§κΈμ @types/react-redux
λ₯Ό μ΄μ λ²μ μΌλ‘ μ€μ νμΌλ©° λͺ¨λ κ²μ΄ μ μμ
λλ€.
@variousauthors μ¬μ© μ€μΈ @types/react
λ° @types/react-redux
λ²μ μ 곡μ ν΄ μ£Όμκ² μ΅λκΉ?
νΈμ§: @
λΌμ΄λΈλ¬λ¦¬μ μ΄λ¦μ΄ νμλμ§ μμ μλ§μ΄ λμμ΅λλ€. μ£μ‘ν©λλ€. μ€λ§:
@variousauthors μ΄ λκΈμ΄
5.0.16 μ΄νμλ 컨ν μ΄λκ° λνλ κ΅¬μ± μμμ μΈν°νμ΄μ€μ μ μμ±μ μΆκ°ν μ μλ κ² κ°μ΅λκΉ? μ΄κ²μ λ΄κ° μ½λλ₯Όλ³΄κ³ μλ κ²μ λλ€.
λ²κ·Έλ reduxμ connect
ν¨μμ λν μ ν μ μκ° ownProps
μ mapPropsToState
κ΅μ°¨ νλ€λ κ²μ
λλ€. μ΄κ²μ λͺ¨λ "컨ν
μ΄λ" κ΅¬μ± μμκ° νμλ "νλ μ ν
μ΄μ
" κ΅¬μ± μμμ 볡μ λ propsκ° μμ΄μΌ νλ€λ κ²μ μλ―Έν©λλ€. μ΄λ μΌλ°μ μΈ redux λμμΈ ν¨ν΄μ κΉ¨λ¨λ¦½λλ€.
μκ°λ PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24764
κΈ°ν λ¬Έμ : https://github.com/DefinitelyTyped/DefinitelyTyped/issues/24922
5.0.15λ‘ λλλ €λ λ¬Έμ κ° μμ ν ν΄κ²°λμ§ μμ΅λλ€. 5.0.15λ κ²½κ³ μμ΄ μ΄λ° μ’
λ₯μ μ½λλ₯Ό μ»΄νμΌνμ§λ§ connect
νΈμΆμμ ν리μ ν
μ΄μ
κ΅¬μ± μμμ λν μ ν κ²μ¬λ₯Ό μΆκ°νλ©΄ μ¬μ ν μ€λ₯κ° λ°μν©λλ€. (λν κ΅¬μ± μμμ MyComponent
μλ μνμ΄ μλ€κ³ κ°μ )
μλ₯Ό λ€μ΄ 5.0.15μμλ μλνμ§λ§ 5.0.16μμλ μλνμ§ μμ΅λλ€.
connect(stateToProps, dispatchToProps)(MyComponent)
κ·Έλ¬λ 5.0.15μμλ μ»΄νμΌλ¬ μ€λ₯ μμ΄ MyComponent
propsλ₯Ό typecheckν μ μμ΅λλ€.
connect<statetoprops, dispatchtoprops, mycomponentprops)(stateToProps, dispatchToProps)(MyComponent)
λν κ΅¬μ± μμ μνμ΄ MyComponent
μλ€κ³ λΆννλ μ€λ₯κ° λ°μν©λλ€.
λλ μ΄κ²μ΄ @Pajn μ μ 리κ°
κ°μ₯ μ μ©ν λκΈ
5.0.15λ‘ λλλ €λ λ¬Έμ κ° μμ ν ν΄κ²°λμ§ μμ΅λλ€. 5.0.15λ κ²½κ³ μμ΄ μ΄λ° μ’ λ₯μ μ½λλ₯Ό μ»΄νμΌνμ§λ§
connect
νΈμΆμμ ν리μ ν μ΄μ κ΅¬μ± μμμ λν μ ν κ²μ¬λ₯Ό μΆκ°νλ©΄ μ¬μ ν μ€λ₯κ° λ°μν©λλ€. (λν κ΅¬μ± μμμMyComponent
μλ μνμ΄ μλ€κ³ κ°μ )μλ₯Ό λ€μ΄ 5.0.15μμλ μλνμ§λ§ 5.0.16μμλ μλνμ§ μμ΅λλ€.
connect(stateToProps, dispatchToProps)(MyComponent)
κ·Έλ¬λ 5.0.15μμλ μ»΄νμΌλ¬ μ€λ₯ μμ΄
MyComponent
propsλ₯Ό typecheckν μ μμ΅λλ€.connect<statetoprops, dispatchtoprops, mycomponentprops)(stateToProps, dispatchToProps)(MyComponent)
λν κ΅¬μ± μμ μνμ΄
MyComponent
μλ€κ³ λΆννλ μ€λ₯κ° λ°μν©λλ€.λλ μ΄κ²μ΄ @Pajn μ μ 리κ°