Skip to content

Wrong "possibly 'undefined'" assertion #29344

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
xobotyi opened this issue Jan 10, 2019 · 6 comments
Closed

Wrong "possibly 'undefined'" assertion #29344

xobotyi opened this issue Jan 10, 2019 · 6 comments
Assignees
Labels
Bug A bug in TypeScript

Comments

@xobotyi
Copy link

xobotyi commented Jan 10, 2019

TypeScript Version:
3.2.2

Search Terms:
Cannot invoke an object which is possibly 'undefined'.
Object is possibly 'undefined'.

Code:

type ElementRef = (element: HTMLElement | null) => void;

type ThumbProps = React.HTMLProps<HTMLDivElement> & {
  elementRef?: ElementRef;
}

type ComponentProps = React.HTMLProps<HTMLDivElement> & {
  thumbYProps?: ThumbProps;
}

class Component extends React.Component<ComponentProps>{
  public thumbYElementRef  = (ref: HTMLElement | null) => {
    this.thumbYEl = ref;
    typeof this.props.thumbYProps!.elementRef === 'function' && this.props.thumbYProps!.elementRef(ref);
  };
}

Expected behavior:
Compillation without errror.
Due to previous check typeof this.props.thumbYProps!.elementRef === 'function' it can't be undefined.

Actual behavior:
Cannot invoke an object which is possibly 'undefined'.
Problem solves if add non-null assertion, but it is unnecessary here!

// this one will compile fine
  public thumbYElementRef  = (ref: HTMLElement | null) => {
    this.thumbYEl = ref;
    typeof this.props.thumbYProps!.elementRef === 'function' && this.props.thumbYProps!.elementRef!(ref);
  };

Playground Link:

Related Issues:

@xobotyi xobotyi changed the title Wrong possibly 'undefined' assertion Wrong "possibly 'undefined'" assertion Jan 10, 2019
@Jessidhia
Copy link

Jessidhia commented Jan 10, 2019

This is probably because of the other assertion you have in there causing TS to think the types are unrelated (hypothesis: it synthesizes one asserted-non-null type for this.props.thumbYProps!, refines that one instance of it, and then it synthesizes another one when you assert it again on the right side so the new instance is missing the refinement).

@xobotyi
Copy link
Author

xobotyi commented Jan 10, 2019

@Kovensky looks like you're right.

public thumbYElementRef = (ref: HTMLElement | null) => {
    this.thumbYEl    = ref;
    const thumbProps = this.props.thumbYProps!;
    typeof thumbProps.elementRef === 'function' && thumbProps.elementRef(ref);
};

Has no errors.

But I'm still thinking that proper behavior is to have no errors in given example.

Dont know about implementation possibility and sadly has no time to read tsc sources.
If you're right about assertion synthesis, issue solvation will require significant changes, cause it supposes identicall equality of variables assertions with same accessor string within one expression statement.

@weswigham
Copy link
Member

weswigham commented Jan 10, 2019

You would be correct. An assertion prevents us from tracking refinements to the asserted reference right now (it's kinda a known limitation). As @xobotyi points out, you can usually work around that by storing the asserted value in a temporary and reusing it.

@xobotyi
Copy link
Author

xobotyi commented Jan 10, 2019

One bad thing about that workaround - useless variable in generated code.

@weswigham
Copy link
Member

@xobotyi aaaaaaand now it's fixed 😉

@xobotyi
Copy link
Author

xobotyi commented Jan 10, 2019

@weswigham a-we-some!
Thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants