Skip to content

Second use of type guard produces different result #52232

Closed as not planned
Closed as not planned
@jasonaden

Description

@jasonaden

Bug Report

🔎 Search Terms

react child.props unknown
ts 18046 reading child prop
typescript user defined type guard fails after second time

🕗 Version & Regression Information

Upgrading project to 4.9.4 from 4.2.4.

  • This changed between versions 4.7 and 4.8.2. I went through until I found where this changed.

⏯ Playground Link

Playground link with relevant code

💻 Code

import React from 'react';

const childArray = [] as any as React.ReactNode[];

childArray.forEach(child => {
  const children = React.isValidElement(child) && child.props.children;
  // child.props is of type "unknown" error. If we swap this line with
  // the one above it, the error moves to the other line of code. Only
  // the line where we read child.props does it correctly type the value.
  // Multiple reads of child.props on the first line also work fine.
  const propsValue = React.isValidElement(child) && child.props.value;
});

// Wrapping the reads with one call to isValidElement will type correctly
childArray.forEach(child => {
  if (React.isValidElement(child)) {
    // no errors here
    const children = child.props.children;
    const propsValue = child.props.value;
  }
});

childArray.forEach(child => {
  const isValid = React.isValidElement(child);
  if (isValid) {
    const children = child.props.children;
    const propsValue = child.props.value;
  // after reading the isValid value a second time, child.props is 
  // again unknown
  } else if (isValid) {
    const children = child.props.children;
    const propsValue = child.props.value;
  }
});

🙁 Actual behavior

All examples fail after the second read of a type guard on props, whether re-running the function or just reading the variable.

🙂 Expected behavior

Should behave consistently no matter if this is the first or second read of the type guard.

Metadata

Metadata

Assignees

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions