1

I have some functions that I would like to reuse as methods across different React classes that are compatible. Is it possible in Typescript to pass the class to a function and have it correctly typed?

I want to do something like this...

// function to be reused across classes
const func = (class: [class type]) => this.setState({ key: "value" })

// class 1 that calls the function in a method
class Foo extends React.Component<{}, {}> {
  callFunc = () => {
    func(this)
  }
  ...
}

// class 2 that calls the function in a method
class Bar extends React.Component<{}, {}> {
  callFunc = () => {
    func(this)
  }
  ...
}

I had this working in JS, but moving to typescript, I am failing to get the proper type in the func args for the classes. I can see that it would have to be some kind of union type to allow for specific classes but IDK how to accomplish it. Any ideas?

Is there a better way to go about doing this?

3
  • why not just const func = (cls: React.Component) => cls.setState({ key: "value" }) ? do you require specific fields on the state to be present in the class ? Then just specify them on the state generic parameter: const func = (cls: React.Component<any, {key: string}>) => cls.setState({ key: "value" }) Commented Jul 15, 2018 at 2:42
  • @TitianCernicova-Dragomir your method gets me halfway there. What if I wanted to access other user defined methods or attributes on the class besides the builtin setState? Commented Jul 15, 2018 at 3:03
  • You would need to add them to your parameter type, const func = (cls: React.Component<any, {key: string}> & { method(): void }) => cls.method Commented Jul 15, 2018 at 3:05

1 Answer 1

1

The function argument needs to specify the contract that needs to be implemented by the client classes. In this case the parameter should be a React.Component that has certain fields in state, and also may have some methods that the function will use. To get the extra methods we can use an intersection type (A & B) to specify that the parameter is a React.Component with some extra methods.

// function to be reused across classes
const func = (cls: React.Component<any, { key: string, optionalKey?: string }> & { requiredMethod(): void; optionalMethod?(): void}) => {
  cls.setState({ key: "value" })
  cls.requiredMethod();
  if(cls.optionalMethod)cls.optionalMethod();
}

// class 1 that calls the function in a method
class Foo extends React.Component<{}, { key: string }> {
  callFunc = () => {
    func(this)
  }
  requiredMethod(){}
}

// class 2 that calls the function in a method
class Bar extends React.Component<{}, {key: string, optionalKey: string }> {
  callFunc = () => {
    func(this)
  }

  requiredMethod(){}
  optionalMethod(){}
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.