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

Type inference problem with generics and Readonly #26600

Closed
jbialobr opened this issue Aug 22, 2018 · 3 comments
Closed

Type inference problem with generics and Readonly #26600

jbialobr opened this issue Aug 22, 2018 · 3 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@jbialobr
Copy link

jbialobr commented Aug 22, 2018

TypeScript Version: 3.0.1

Search Terms:
Type inference generics Readonly

Code

class ReactComponent<P>
{
  public constructor(public props: Readonly<P>)
  {
  }
}

interface XampleProps
{
  x?: boolean;
}

class Xample<PT extends XampleProps = XampleProps> extends ReactComponent<PT>
{
  public render()
  {
    const localX = this.props.x;
    return this.doSthWithX(localX || false);
  }

  private doSthWithX(data: boolean): boolean
  {
    return data;
  }
}

Expected behavior:

Code should compile with no errors.

Actual behavior:

The compiler complains about the return this.doSthWithX(localX || false); line. It says:

Argument of type 'PT["x"]' is not assignable to parameter of type 'boolean'.
  Type 'boolean | undefined' is not assignable to type 'boolean'.
    Type 'undefined' is not assignable to type 'boolean'.

Adding the explicit type for localX solves the problem.

class Xample<PT extends XampleProps = XampleProps> extends ReactComponent<PT>
{
  public render()
  {
    const localX: boolean | undefined = this.props.x;
    return this.doSthWithX(localX || false);
  }

  private doSthWithX(data: boolean): boolean
  {
    return data;
  }
}

Removing the Readonly from the ReactComponent also eliminates the compiler error.

Playground Link:

Related Issues:
Perhaps #26418

@ghost
Copy link

ghost commented Aug 22, 2018

Simplified repro:

function f<P extends { x?: boolean }>(props: { [K in keyof P]: P[K] }): boolean {
    return props.x || false;
}

@ghost ghost added the Bug A bug in TypeScript label Aug 22, 2018
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.2 milestone Aug 22, 2018
@RyanCavanaugh
Copy link
Member

Requires strictNullChecks on; not a regression

@RyanCavanaugh RyanCavanaugh added Working as Intended The behavior described is the intended behavior; this is not a bug Design Limitation Constraints of the existing architecture prevent this from being fixed and removed Bug A bug in TypeScript Working as Intended The behavior described is the intended behavior; this is not a bug labels Oct 10, 2018
@RyanCavanaugh RyanCavanaugh removed this from the TypeScript 3.3 milestone Oct 10, 2018
@RyanCavanaugh
Copy link
Member

We'd need #22348 or something similar to correctly typecheck this -- it requires the checker understanding that all of the truthy values of the mapped type's x property are boolean, which is not immediately apparent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants