score:0

Accepted answer

Apart from the suggested solutions, you may also use discriminating unions: link to the doc which is designed specifically to solve this kind of situations (refer the doc).

like this:

type DogProps = {
  animalName: "dog";
  bark: () => void;
}

type FishProps = {
  animalName: "fish";
  swim: () => void;
}

type AnimalProps = DogProps | FishProps;

const Animal = (props: AnimalProps) => {
  if(props.animalName === 'dog') {
      props.bark();
  } else {
      props.swim();
  }
}

TS Playground link: https://tsplay.dev/NddryN


Destructing isn't possible until you narrow down the type like this (you see other props resolve appropriately without hassle of checking):

type DogProps = {
  animalName: "dog";
  bark: () => void;
  dogProp: string;
}

type FishProps = {
  animalName: "fish";
  swim: () => void;
  fishProp: number;
}

type AnimalProps = DogProps | FishProps;

const Animal1 = (props: AnimalProps) => {
  if(props.animalName === 'dog') {
     const { bark, dogProp } = props;
      bark();
  } else {
    const {swim, fishProp} = props;
      swim();
  }
}

see this: https://tsplay.dev/N9pn7w

score:0

You can simply check if the function exists before calling it.

if (animalName === 'dog' && typeof bark === 'function') {
  bark();
}

If you feel like that is too verbose, you can also take advantage of optional-chaining to do the same thing.

if (animalName === 'dog') {
  bark?.(); // Will only invoke bark() if it's defined
}

Optional-chaining is supported in TypeScript since version 3.7.


Related Query

More Query from same tag