Starting with TypeScript 2.8, you can also do this with the infer keyword. This should only be used for more complicated cases (arrays nested in promises, etc.). Otherwise, it is overly verbose.
type GetElementType<T extends any[]> = T extends (infer U)[] ? U : never;
For example:
// ElementType === string
type ElementType = string[] extends (infer U)[] ? U : never;
The infer keyword is very powerful and can extract any type out of larger type. For example, if the type was a function that returned an array:
type FncType = () => [{ name: string }];
// Output === { name: string }
type Output = FncType extends () => (infer U)[] ? U : never;
You can also use the infer keyword in generic types:
type GetArrayReturnType<T> = T extends () => (infer U)[] ? U : never;
// Output === { name: string }
type Output = GetArrayReturnType<() => [{ name: string }]>;
type foo = Array<T>- is this question asking how to get "T", or something else?