arraystypescripttypeguardsgeneric-type-parameters

Typescript Typeguard check if array is of type


I want to write a typeguard to check if all children of array are of type T thus making it an Array where T is a generic type

TS Playground

// Assume arr of any type but Array
const arr: any[] = [
  {
    foo: "bleh1",
    bar: 1
  },
  {
    foo: "bleh2",
    bar: 2
  },
]

interface newType {
  foo: string
  bar: number
}

// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(arr: any): arr is Array<T> => {
  // TypeScript mastery needed here
  return true
}

if(isArrayOf<newType>(arr)){
  arr
}


Solution

  • The best thing you could do is this:

    const arr: NewType[] = [
      {
        foo: "bleh1",
        bar: 1
      },
      {
        foo: "bleh2",
        bar: 2
      },
    ]
    
    interface NewType {
      foo: string
      bar: number
    }
    
    type TypeOfArrayElements<T> = T extends Array<infer U> ? U : never;
    
    type ArrayType = TypeOfArrayElements<typeof arr>;
    

    TypeScript will never be able to guess that the array typed as any[] actually contains NewType elements. Like everything in TypeScript, type predicates are static and won't return a type dynamically based on what is passed as a parameter at runtime. But if you type it as NewType[], then you can extract the NewType type from it.