This is a follow-up question to this more basic SO question here: How do I make Typescript understand that one argument can be used as a discriminant property for another object argument?
The problem is best explained with code:
type Types = "Foo" | "Bar";
interface ObjOne {
one: "one";
two: "two";
}
interface ObjTwo {
three: "three";
four: "four";
}
type ExtractRelatedObject<T extends Types> = T extends "Foo"
? ObjOne
: T extends "Bar"
? ObjTwo
: never;
interface Baz<T extends Types> {
type: T;
relatedObject: ExtractRelatedObject<T>;
arrayOfRelatedObject: Array<ExtractRelatedObject<T>>
}
function componentOne({type, relatedObject, arrayOfRelatedObject}: Baz<"Foo"> | Baz<"Bar">) {
if (type === "Bar") {
relatedObject.three;
arrayOfRelatedObject.map(relObj => relObj)
}
}
interface ComponentTwoProps<T extends Types> {
type: T
arrayOfRelatedObject: Array<ExtractRelatedObject<T>>
}
function componentTwo<T extends Types>({type, arrayOfRelatedObject}: ComponentTwoProps<T>) {
arrayOfRelatedObject.map((relObj, index, arr) => {
return componentOne({type, relatedObject: relObj, arrayOfRelatedObject: arr })
})
}
Playground link.
Typescript does not understand that arr
and relObj
are related, and somehow tries to cross-assign arr
.
What is wrong here, and how can it be fixed?