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?