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

Strange "unconstrained" behavior with React components #9007

Closed
ansonlouis opened this issue Feb 8, 2023 · 5 comments
Closed

Strange "unconstrained" behavior with React components #9007

ansonlouis opened this issue Feb 8, 2023 · 5 comments
Labels

Comments

@ansonlouis
Copy link

I'm seeing what I believe to be unexpected pass-cases and, in general, inconsistent behavior with underconstrained component props. I've boiled down the example to something simple enough to illustrate the problem but still gets to the brunt of my real-world use-case.

The general premise is being able to have:

  • a union of types (with type and state fields)
  • a component that will take in the common type field as well as take in a component that should expect the corresponding state

In general, I've gotten Flow to handle this well (albeit inconsistently) until I start nesting the component in something else (even just a <div/>)

Example:

type Data1 = {type: 'one', state: 1};
type Data2 = {type: 'two', state: 2}; 

type DataSource =
    | Data1
    | Data2;

type Props<D: DataSource> = {
    type: D['type'],
    C: ComponentType<{s: D}>
};

function DataComponent<D: DataSource>({type, C}: Props<D>): Node { ... }

// good
<DataComponent type="one" C={(p: {s:Data1}) => <div/>} />;
<DataComponent type="two" C={(p: {s:Data2}) => <div/>} />;
// expected failure
<DataComponent type="two" C={(p: {s:Data1}) => <div/>} />;

Looking at the TryFlow link below, Flow handles this situation well except in the last cases, which I'm not sure why. This feels like a bug, but maybe I'm missing something.

Try Flow

@SamChou19815
Copy link
Contributor

This is expected behavior. The difference is caused by whether the generic react component has some typing context coming from the parent. If there is a usable typing context, then even if some type argument cannot be solved from arguments and return hints, we will happily use default of the type parameter or bound (mixed if not specified) of the type parameter as the solution.

@SamChou19815 SamChou19815 closed this as not planned Won't fix, can't repro, duplicate, stale Feb 8, 2023
@ansonlouis
Copy link
Author

So the react element tree changes typing context?

function Component<T: number>(pprops: {a:T}): Node {}

// pass (good)
<Component a={1} />;

// fail (good)
<Component a="str" />;

// pass?
(
    <div>
        <Component a={true} />
    </div>
)

TryFlow

@SamChou19815
Copy link
Contributor

The new example seems like a bug. I will reopen and investigate.

@SamChou19815 SamChou19815 reopened this Feb 10, 2023
@ansonlouis
Copy link
Author

Thanks. Sorry, it took me a second to realize the issue could be boiled down more simply

@ansonlouis
Copy link
Author

198.2 seems to fail properly, anyways

facebook-github-bot pushed a commit that referenced this issue Feb 13, 2023
Summary:
The cache was properly rolled back before, but it was dropped by mistake in D41361086 (f05653c).

Close #9007

Changelog: [errors] Some additional errors might be revealed after a correctness fix in implicit instantiation. Example: https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBLAtgBzgJwBcwAlAUwEMBjYqfOLMAcn0pqYG5UoBXAOxoY4fMAGEGePmT6EAPABUAXGD48 (114c051e26016bfbd117d80634e48c55442fdf2f)sAIzL4AfAAocOejgDOygN4VF8gL4BKZeWqEAJADk4AEzJgz19MGAwKAoMGFRZDwwAN21ZcVxhaWIKAF4zQnweMmswYFjgSJiuIA

Reviewed By: panagosg7

Differential Revision: D43207712

fbshipit-source-id: 86b80d0a42a01d654e2e1c42d9a65b0f176fe9b0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants