Edit 1:
This answer has two shortcomings (mentioned in comments)
- The property needs not be own for it to exist on the object
x = {a: 1}; y = Object.create(x); y.b = 2
- The function requires you to manually enumerate all the keys of the object. Thus can introduce human error
I think the solution can still be used as workaround in specific circumstances
Original:
If an array a is of type newType[] then every element of a , consider x = a[0] will be of type newType. x is of type newType because x satisfies all properties and methods of type newType.
Thus if reversed , if x y z are of type newType and they are the only and all elements of array a, Thus every element of a are of type newType, which satisfies the condition for a to be of type newType[]
// Check if obj has all keys props[]
const hasAllProperties = <T,>(obj: any, props: (keyof T)[]): obj is T => {
return props.every((prop) => {
// console.log(prop)
return Object.prototype.hasOwnProperty.call(obj, prop)})
}
// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(obj: any[], props: (keyof T)[]): obj is T[] => {
// Check if every elements have all keys in props
return obj.every((ele) => {
// console.log(ele)
return hasAllProperties<T>(ele,props)
}
)
}
if (isArrayOf<newType>(arr, ["foo", "bar"])) {
console.log("arr is of newType[]")
}
TS Playground
typescript const isArrayOf = <T>(arr: any[], type: new (...args: any[]) => T): arr is T[] => { return arr.every((item) => item instanceof type) }