TypeScript - narrow type by function asserts

283 Views Asked by At

I'm trying to get TS to narrow a type that I am manually modifying in a function:


interface Node {
  parent: string | null;
}

interface NoParent extends Node {
  parent: null;
}

interface HasParent extends Node {
  parent: string;
}

// Node -> HasParent
// ok, Node now known to have parent
export const setParent = (n: Node): asserts n is HasParent => {
  n.parent = 'parent added';
};

// Node -> NoParent
// ok, Node now known to have no parent
export const unsetParent = (n: Node): asserts n is NoParent => {
  n.parent = null;
};

// NoParent -> HasParent
// error: A type predicate's type must be assignable to its parameter's type.
export const addParent = (n: NoParent): asserts n is HasParent => {
  // ... use n as NoParent ...

  (n as Node).parent = 'parent';
};

// HasParent -> NoParent
// error: A type predicate's type must be assignable to its parameter's type.
export const removeParent = (n: HasParent): asserts n is NoParent => {
  // ... use n as HasParent ...

  (n as Node).parent = null;
};

I need to write addParent and removeParent with a specific type (not Node) because those functions also serve as type guards in calling code. Is there a way to tell TS that I know the object I'm returning is a type that is not compatible with the parameter?

0

There are 0 best solutions below