Skip to content

Type inference issue JSX with generic #30057

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

Closed
ulrichb opened this issue Feb 22, 2019 · 11 comments
Closed

Type inference issue JSX with generic #30057

ulrichb opened this issue Feb 22, 2019 · 11 comments
Assignees
Labels
Bug A bug in TypeScript Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution

Comments

@ulrichb
Copy link

ulrichb commented Feb 22, 2019

TypeScript Version: 3.3.3333

This is a follow-up for #27986 (see also this comment). It already has been fixed and the type inference worked fine since then. But now, the exact same compiler error (see original issue for code snippet) appeared after updating @types/react:

image

I've tacked it down and it happened exactly with @types/react@16.7.21 (version @types/react@16.7.20 and before works).

I've generated a diff of these two versions: Compare.pdf

And here are the full packages: both_versions.zip

@weswigham
Copy link
Member

weswigham commented Feb 22, 2019

I'm not seeing the same error (or any error) when I try to make a repro - what are your compiler options?

@weswigham
Copy link
Member

Actually, hold on (well, maybe in addition to that question), that looks like VS - what version of the typescript SDK do you have installed in VS? IIRC the TS version installed in your project by npm has no bearing on the version used by VS for editor features.

@ulrichb
Copy link
Author

ulrichb commented Feb 22, 2019

Hi. Also happens via tsc. Here is the command line.

>npx tsc -t es2017 -m commonjs --jsx react --strict TypeScriptIssue27986.tsx
TypeScriptIssue27986.tsx:24:26 - error TS2322: Type '() => Promise<ErrorResult | { success: true; }>' is not assignable to type '() => Promise<{ success: true; }>'.
  Type 'Promise<ErrorResult | { success: true; }>' is not assignable to type 'Promise<{ success: true; }>'.
    Type 'ErrorResult | { success: true; }' is not assignable to type '{ success: true; }'.
      Property 'success' is missing in type 'ErrorResult' but required in type '{ success: true; }'.

24             <AsyncLoader asyncLoad={load}>{result =>
                            ~~~~~~~~~

  TypeScriptIssue27986.tsx:16:34
    16 async function load(): Promise<{ success: true } | ErrorResult> {
                                        ~~~~~~~
    'success' is declared here.
  TypeScriptIssue27986.tsx:8:14
    8     readonly asyncLoad: () => Promise<TResult>;
                   ~~~~~~~~~
    The expected type comes from property 'asyncLoad' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<AsyncLoader<{ success: true; }>> & Readonly<{ children?: ReactNode; }> & Readonly<AsyncLoaderProps<{ success: true; }>>'


Found 1 error.

>npx tsc -v
Version 3.3.3333

Same with TSC 3.4.0-dev.20190222.

@ulrichb
Copy link
Author

ulrichb commented Feb 22, 2019

(As in #27986 --strict is necessary.)

@ulrichb
Copy link
Author

ulrichb commented Feb 22, 2019

Oh, that's interesting: My "more simple repro" from the comments does not emit an error. (Only the full sample in the issue description.)

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 27, 2019
@ulrichb
Copy link
Author

ulrichb commented Mar 4, 2019

@weswigham Did you have a look on this? Atm. this prevents me from upgrading to React 16.8 (typings).

@weswigham
Copy link
Member

weswigham commented Mar 9, 2019

Minimal repro without involving react:

// @strict: true
interface Box<T> {
    v: T;
}

interface ErrorResult {
    readonly error: true
}

interface AsyncLoaderProps<TResult extends {}> {
    readonly asyncLoad: () => Box<TResult>;
    readonly children: (result: Exclude<TResult, ErrorResult>) => string;
}

class AsyncLoader<TResult extends {}> {
    constructor(props: string, context: any);
    constructor(props: AsyncLoaderProps<TResult>);
    constructor(...args: any[]) {}
}

function load(): Box<{ success: true } | ErrorResult> {
    return null as any;
}

new AsyncLoader({
    asyncLoad: load,
    children: result => result.success as any,
}); // should work fine

eliminating either constructor overload removes the error- which means you can work around the bug in your own code by writing your own constructor out explicitly in your Component subtype.

@ulrichb
Copy link
Author

ulrichb commented Mar 9, 2019

Many thanks for having a look. And thanks for the hint with the c'tor workaround!

@weswigham weswigham added Bug A bug in TypeScript Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution and removed Needs Investigation This issue needs a team member to investigate its status. labels Mar 9, 2019
@ulrichb
Copy link
Author

ulrichb commented Mar 11, 2019

@weswigham Thank you very much for the fix!

@city41
Copy link

city41 commented May 1, 2019

I believe I am seeing this issue with TS 3.4.5

This file fails to compile:

import React from 'react';

interface IErrorProps {
    error: string;
}

export default function foo<TErrorProps extends IErrorProps>(
    ErrorCmp: React.ComponentType<TErrorProps>
) {
    return class extends React.Component {
        render() {
            return <ErrorCmp error="test error" />;
        }
    }
}

with the error Type '{ error: string; }' is not assignable to type 'TErrorProps'

But if I downgrade to TS 3.1.4, it compiles without issue.

This happens for me whether I have @types/react at 16.7.20 installed or the latest, 16.8.15

@city41
Copy link

city41 commented May 1, 2019

My above comment is not correct, it looks like I am seeing an improvement/bug fix from TS 3.1 to 3.2, more info here: https://stackoverflow.com/questions/55942402/when-using-generic-react-components-get-error-in-ts-3-2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution
Projects
None yet
Development

No branches or pull requests

4 participants