Что-то вроде такого можно сделать:
type TestResult<T extends string[] | CustomClass[]> = T extends CustomClass[] ? T : void;
function test<T extends string[] | CustomClass[]>(data: T): TestResult<T> {
if (data[0] instanceof CustomClass) {
return data as TestResult<T>;
}
return undefined as TestResult<T>;
}
https://www.typescriptlang.org/play?#code/CYUwxgNg...
Но без приведения типов внутри не обойтись. Ну и как писал
WbICHA в комментах, такие типы не безопасны для пустого массива, так как в рантайме типов нет, а значит и нет возможности проверить, какого типа пришел пустой массив.