Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referring to the type of function parameters #17935

Closed
MichaelTontchev opened this issue Aug 21, 2017 · 5 comments
Closed

Referring to the type of function parameters #17935

MichaelTontchev opened this issue Aug 21, 2017 · 5 comments
Labels
Needs More Info The issue still hasn't been fully clarified

Comments

@MichaelTontchev
Copy link

MichaelTontchev commented Aug 21, 2017

To use Redux properly, when passing a callback that also relies on other arguments to a component, you're supposed to pass the bound callback and separately pass the arguments as other props to the component, and then have the component compose the two inside of it.

(this is instead of doing the simple callback={() => this.theCallback(myParam)}, which will cause a rerender because a new function is created every time this code path is hit).

However, I am having trouble making this type-safe in the general case.

So for example, if you have a Button component that needs to take an onClick callback, you want the parent component to call it like

<Button onClick={this.someBoundCallback} onClickArgument1={someArgument}/>

In Button, you will have IButtonProps declared like

interface IButtonProps {
    onClick(argument1: any): void;
    onClickArgument1: any;
}

However, this is not type-safe.

How to satisfy the general case where the onClick handler can take in an arbitrary parameters, with arbitrary types (depending on the context in which it's used by the parent component)?

Even if we don't have to solve the arbitrary argument list size case, the above solution is already not type-safe because of the any.

If we could reference the types of the parameters of a function, it seems that it would solve the problem.

Is there any other solution with the tools we have available now in TS?

(Yes, we could wrap the Button component in another component that contains the type information, but that becomes quite heavy - every time we want to use the component we have to wrap it inside of a new component).

@aluanhaddad
Copy link
Contributor

Do you mean something like this?

import React from 'react';

function Button<T, U>(props: {
  onClick: (x: typeof props['arg1'], y: typeof props['arg2']) => void, arg1: T, arg2: U
}) {
  return <div></div>;
}

class C extends React.Component {
  onClick = (x: 1, y: 'hello') => console.log(x, y);

  render() {
    return <Button onClick={this.onClick} arg1={1} arg2={'hello'} ></Button>;
  }
}

@mhegazy mhegazy added the Needs More Info The issue still hasn't been fully clarified label Aug 22, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Aug 22, 2017

possibly related to #12265 and #5453

@MichaelTontchev
Copy link
Author

@aluanhaddad - like that, yeah, but it's not clear to me how to achieve it when using an interface for the props.

@mhegazy - could you explain what more info you'd like me to provide?

@mhegazy
Copy link
Contributor

mhegazy commented Aug 22, 2017

A more detailed explanation/code snippet of the scenario you are trying to achieve.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 5, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Sep 5, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs More Info The issue still hasn't been fully clarified
Projects
None yet
Development

No branches or pull requests

3 participants