export type ITreeNode1 = {
value: {
method: number;
enabled: boolean
}
};
export type ITreeNode2 = {
value: {
age: number
enabled: boolean
}
};
export type ITreeNode3 = {
value: {
name: string
}
};
export type SelectedNode = ITreeNode1 | ITreeNode2 | ITreeNode3;
const example = (n: SelectedNode) => {
if ("value" in n && "enabled" in n.value) {
const node = n; // still shows SelectedNode type, cannot infer that is either TreeNode1 or TreeNode2?
}
}
#Why cannot it infer the type from union?
21 messages · Page 1 of 1 (latest)
the "enabled" in n.value check narrows n.value, but not n
If you've got control over the data-structure writing this as a discriminated union would be a lot easier than doing in checks
!hb discriminated union
Understand how TypeScript uses JavaScript knowledge to reduce the amount of type syntax in your projects.
you mean adding "kind"/"type" field?
i did something like this:
export const hasEnabledField = (node: UNodeTypes): node is Extract<UNodeTypes, {value: {enabled: boolean}}> => {
return "value" in node && "enabled" in node.value
}
yes
typeguards are inherently unsafe, if you can use normal narrowing you should do that instead
but then i would have to manually update the function that checks the type every time i add a new type of node, making it not very flexible, right?
if (node.type === 1 || node.type === 2
) {
return true
} else {
return false
}
it makes it controllable
but if i make NodeTree3 have "enabled" field then i will have to add the check to the function manually and it wouldnt give any warnings if i forgot to do it, right?
Or am i missing something
yeah that's correct
well i guess thats not really great for my use case then
There are ways to structure checks where you have to account for every case and you'll get a compiler error if you don't
Or you could eliminate the cases that don't have the property:
function example(node: TreeNode) {
// Ignore the cases that *don't* have enabled
if(node.kind === "node3") return;
// Will compile error if you add a new kind that doesn't have enabled and don't add it above
console.log(node.value.enabled);
}
But yeah, the special type-guard with Extract is fine too, but it would quickly grow annoying if you had a lot of those.
wdym it would grow annoying?
I mean if you write hasEnabledField and hasOtherField and hasYetAnotherField that's a lot of very specific utilities that you have to make sure the unchecked type is correct on. Maybe that's not realistic, I don't know what your problem domain looks like
wouldnt that be the same using your solution?
If i wanted to check for another field i would still need to do this
if kind == something
I guess for me writing specific checks the place I'm doing checks is less annoying than having a bunch of utility type-guards with complex type signatures; but I guess it just depends on what you're doing