Search code examples
reactjstypescriptreact-spring

Using react-spring in a TypeScript component class throwing compilation problems


I am trying to use a swipeable button in my component similar to this example I was able to make it work with React but TypeScript is giving me problems. Please see the compilation errors below:

import * as React from 'react'
import { withGesture } from 'react-with-gesture'
import { Spring, animated } from 'react-spring'

interface Props {
  name: string
  sex: string
  age: string
  xDelta?: number
  down?: boolean
}

@withGesture
export class Person extends React.Component<Props, {}> {
  render() {
    const { xDelta, down, children } = this.props
    let x = 0
    return (
      <Spring native to={{ x: down ? xDelta : 0 }} immediate={name => down && name === 'x'}>
        {({ x }) => (
          <div className="item" style={{ backgroundColor: xDelta < 0 ? '#FF1C68' : '#14D790' }}>
            <animated.div className="fg" style={{ transform: x.interpolate(x => `translate3d(${x}px,0,0)`) }}>
              {down && Math.abs(xDelta) > 50 ? (xDelta < 0 ? 'Cancel' : 'Accept') : children}
            </animated.div>
          </div>
        )}
      </Spring>
    )
  }
}

export default Person

ERROR in [at-loader] ./src/components/Person.tsx:19:62 TS2322: Type '(name: string) => boolean | undefined' is not assignable to type 'boolean | string[] | ((key: string) => boolean) | (false & ((name: string) => boolean | undefined)) | (true & ((name: string) => boolean | undefined)) | (string[] & ((name: string) => boolean | undefined)) | (((key: string) => boolean) & ((name: string) => boolean | undefined)) | undefined'. Type '(name: string) => boolean | undefined' is not assignable to type '(key: string) => boolean'. Type 'boolean | undefined' is not assignable to type 'boolean'. Type 'undefined' is not assignable to type 'boolean'.

ERROR in [at-loader] ./src/components/Person.tsx:21:59 TS2532: Object is possibly 'undefined'.

ERROR in [at-loader] ./src/components/Person.tsx:23:33 TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. Type 'undefined' is not assignable to type 'number'.

ERROR in [at-loader] ./src/components/Person.tsx:23:49 TS2532: Object is possibly 'undefined'. ℹ 「wdm」: Failed to compile.

Is this something to do with my tsconfig settings? I have been trying last 10 hours to be able to run react-spring with a gesture example using Typescript and my own config files. I would appreciate directions.

Thanks.


Solution

  • Since the xDelta and down props are optional, they will be undefined if they weren't passed in. I assume you have the strictNullChecks compiler option (or the strict option, which includes it) enabled, so TypeScript is checking that you deal with undefined properly. In this case, the easiest solution is probably to take advantage of the defaultProps support by making the xDelta and down props non-optional from the perspective of the component implementation (remove the ? marks in Props) and adding the following in class Person (substitute the default values you actually want):

      static defaultProps = {
        down: false,
        xDelta: 0
      };
    

    After I make this change, I'm left with one noImplicitAny error on the x parameter in x => `translate3d(${x}px,0,0)`. To resolve that error, specify the correct type for x: I'm guessing it's number or string.