Oi Charles,
Seu código está quase perfeito 👍! 
A lógica de validação da extensão está correta, mas notei que você está chamando a função entrada() repetidamente dentro do bloco else. Isso pode levar a um loop caso o usuário continue inserindo extensões inválidas.
Uma forma mais elegante de lidar com isso seria usar um loop while para solicitar a entrada do usuário até que uma extensão válida seja fornecida. 
Veja um exemplo:
import 'dart:io';
void main() {
  String? tiposArquivos;
  List<String> tiposExtensoes = ['pdf', 'jpg', 'png', 'docx'];
  bool validacaoExtensao(String? tiposArquivos) {
    return tiposArquivos != null && tiposArquivos.isNotEmpty &&
        tiposExtensoes.contains(tiposArquivos);
  }
  do {
    print('Tipo de arquivo a ser enviado: ${tiposExtensoes.join(', ')}.');
    tiposArquivos = stdin.readLineSync()?.toLowerCase();
    if (tiposArquivos == null || tiposArquivos.isEmpty || !validacaoExtensao(tiposArquivos)) {
      print('Arquivo não suportado. Digite novamente');
    }
  } while (!validacaoExtensao(tiposArquivos));
  print('Arquivo permitido.');
}
Neste exemplo, o loop do...while garante que a entrada seja solicitada até que uma extensão válida seja inserida. 
Isso torna o código mais conciso e evita repetições desnecessárias. 💪
Para saber mais: Documentação oficial do Dart sobre loops.
Continue praticando e explorando as possibilidades da linguagem! 💻