The goal is to find a reusable way to filter out an array of items, the array will implement one of two interfaces
Showing a code example of what I wanna do would be best:
interface IDuration {
start: number;
end: number;
}
interface IRelativeDuration {
relativeStart: number;
relativeEnd: number;
}
export const enforceBoundries = (
point: number,
items: Array<IDuration> | Array<IRelativeDuration>,
): void => {
let startKey: string
let endKey: string
// **CAN'T FIGURE THIS OUT**
if(/* iDuration */) {
startKey = 'start'
endKey = 'end'
} else {
startKey = 'relativeStart'
endKey = 'relativeEnd'
}
items.forEach(item => {
if(item[startKey] > point) {
//....
}
})
}
The answer most likely would be in Generic Constraints, but I am not that good with typescript
Tried many conditions in the if
but can't figure out a way that would make the app compiles
CodePudding user response:
You can try to use typeof to know if the type of item. Then you have to cast it to its type.
CodePudding user response:
As far as i know, there is now way to check if a json-object matches a interface at runtime. There a no interfaces at Javascript, at all.
"typeof" would not work either because the result would always be "object"
So a solution could be to utilise Object.keys() and check if all required properties are present at the object:
interface IDuration {
start: number;
end: number;
}
interface IRelativeDuration {
relativeStart: number;
relativeEnd: number;
}
export const enforceBoundries = (
point: number,
items: Array<IDuration> | Array<IRelativeDuration>,
): void => {
items.forEach((item: IDuration | IRelativeDuration) => {
const props = Object.keys(item) // get all keys from item-object
let startValue = null
// check if item meets one of the two interfaces
if (props.includes("start") && props.includes("end")) {
// it is a IDuration
startValue = (item as IDuration).start
} else if (props.includes("relativeStart") && props.includes("relativeEnd")) {
// it is a IRelativeDuration
startValue = (item as IRelativeDuration).relativeStart
} else {
// no IDuration and no IRelativeDuration
throw new Error("something went wrong...");
}
if (startValue === null)
throw new Error("startValue should never be null at this point...");
if (startValue > point) {
//....
}
})
}