score:1

you can't use destructuring of union of interfaces and expect ts to discriminate which interface is the relevant one at runtime. you also can't use typeof or instanceof at runtime to dynamically infer it yourself.

what you could do is destructuring all attributes by casting props object to some interface and extract the relevant attributes each time, something like:

const element: react.fc<icommon> = props => {
  const {name, age} = props as ifirst;
  const {cars, friends} = props as isecond;
  return (...);
}

please notice that you cannot declare name twice in the same scope, so i declared it only once...

if you want to be sure which type you're dealing with, you could determine the 'actual' type without any warnings using casting:

if ((props as isecond).cars !== undefined) {
    const {name, cars, friends} = props as isecond;
}

same goes with age and ifirst.

if you want to do a little better practice - there is an article i found about discriminated unions and destructuring in typescript.

another way is to 'add' your props object's type the desired attributes using the is keyword, while also determining the actual type of your props:

function hascars(obj: any): obj is isecond {
  return !!obj && typeof obj === "object" && "cars" in obj;
}

function hasage(obj: any): obj is ifirst {
  return !!obj && typeof obj === "object" && "age" in obj;
}

const element: react.fc<icommon> = (props) => {
  if (hascars(props)) {
    // props is now exactly of type isecond
    const {name, cars, friends} = props; // this is a valid statement now
    props.friends // also won't cause the red line...
  }
  else if (hasage)) {
    // same here but with ifirst
  }
}

Related Query

More Query from same tag