Issue
I have an object with two values. I would like to type check one value conditionally based on the value of its peer. I have looked at various solutions but I cannot get it to work how I would like it to.
I can do something like this (source):
type TypeFruit = "apples" | "bananas";
type TypeMetal = "iron" | "copper";
type InterfaceItem =
| {
item: "fruit";
type: TypeFruit;
}
| {
event: "metal";
type: TypeMetal;
};
type ItemTypeParameters = InterfaceItem["type"];
type Item = {
item: "fruit" | "metal";
type: ItemTypeParameters;
};
But that produces:
// ✅ Correct
assignItem({
item: "fruit",
type: "apples",
});
// ✅ Correct
assignItem({
item: "fruit",
type: "copper",
});
What I would like to do is set up the code so that the outcome would be like this:
// ✅ Correct
assignItem({
item: "fruit",
type: "apples",
});
// ❌ Wrong
assignItem({
item: "fruit",
type: "copper",
});
Is there a way to do this? I've looked at ConditionalTypes, which seems like what I would want, but found them confusing and it seemed like they were for other scenarios like extending types conditionally.
Solution
Your original InterfaceItem
is already giving you the shape you're looking for - where item: "fruit"
is necessarily paired with (and only paired with) a TypeFruit
. All you need is that, and nothing else.
type TypeFruit = "apples" | "bananas";
type TypeMetal = "iron" | "copper";
type InterfaceItem =
| {
item: "fruit";
type: TypeFruit;
}
| {
event: "metal";
type: TypeMetal;
};
declare const assignItem: (item: InterfaceItem) => null;
assignItem({ // Works
item: "fruit",
type: "apples",
});
assignItem({ // Fails
item: "fruit",
type: "copper",
});
Answered By - CertainPerformance
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.