I have the following types defined:
export type Property =
| BooleanProperty
| NumberProperty
| IntegerProperty
| StringProperty
| ObjectProperty
| ArrayProperty;
export interface OneOf {
oneOf: PropertyOrKeyword[];
}
export interface AnyOf {
anyOf: PropertyOrKeyword[];
}
type Keyword = OneOf | AnyOf;
export type PropertyOrKeyword = Property | Keyword;
In my code, I then have this:
const val = parent[objName]; // This is a PropertyOrKeyword type
if ("oneOf" in parent[objName]) {
const index = val.oneOf.findIndex(
(obj: Property) => obj.title === title
);
val.oneOf[index] = ref(title);
}
When I hover over val.oneOf
, however, I see the following error:
Property 'oneOf' does not exist on type 'PropertyOrKeyword'.
Property 'oneOf' does not exist on type 'BooleanProperty'.
It seems that maybe there are too many types being unioned, and TypeScript isn't able to detect that oneOf
is a field on one of those types? Or am I doing something weird here? Seems to me that this should be working, and the in
phrase should help TypeScript discover that val
is of the OneOf
type.
Am I missing something here? Does it have to do with the recursive nature of the types?
CodePudding user response:
TypeScript cannot understand that val
and parent[objName]
are the same object, even if the assignment is at the line before the check. You should check directly the val
property.
const val = parent[objName]; // This is a PropertyOrKeyword type
if (typeof val === "object" && "oneOf" in val) {
const index = val.oneOf.findIndex(
(obj: Property) => (obj as ({title: string})).title === title
);
val.oneOf[index] = ref(title);
}
Here is a complete TS Playground solving your code.
As a side note, you should also check that the obj
has the title property or casting it to somewhat like { title: string }
before comparing the value of the title
property in your findByIndex
callback