Ad

TS: Pass Union Type To Function That Accepts Subtype

- 1 answer

// Example Code: 

type Type1 = {
  a: string;
};

type Type2 = {
  a: string;
  b: number;
};

type Type3 = {
  a: string;
  b: string;
  c: string;
  d: object;
};

type Types = Type1 | Type2 | Type3;

function getType(thing: Types) {
// ...
}

function processByType(thingsToProcess: Types) {
  if (getType(thingsToProcess) === "type1") {
    processType1(thingsToProcess);
  } else if (getType(thingsToProcess) === "type2") {
    processType2(thingsToProcess);
  } else if (getType(thingsToProcess) === "type3") {
    processType3(thingsToProcess);
  } else {
    throw Error("Unknown type");
  }
}

function processType1(t: Type1) {}
function processType2(t: Type2) {}
function processType3(t: Type3) {}

In the above code, ts wont let me pass an object of Type to any function but processType1 since Type1 has attributes in common with the rest.

How can I change my code to make this setup work?

Ad

Answer

Instead of having if (getType(thingsToProcess) === "type1") {, perform the comparison inside the function so that the function can be used as a type guard.

// example implementation
function isType<T extends Types>(thing: Types, a: string): thing is T {
    return thing.a === a;
}

function processByType(thingsToProcess: Types) {
  if (isType<Type1>(thingsToProcess, "type1")) {
    processType1(thingsToProcess);
  if (isType<Type2>(thingsToProcess, "type2")) {
    processType2(thingsToProcess);
  if (isType<Type3>(thingsToProcess, "type3")) {
    processType3(thingsToProcess);
  } else {
    throw Error("Unknown type");
  }
}
Ad
source: stackoverflow.com
Ad