<template>
  <!--
    Os componentes de célula possuem props tipadas por `tipo`.
    Aqui o TS do template não consegue inferir o narrowing do union do `dados`,
    então normalizamos para `unknown` e deixamos a validação de runtime do Vue.
  -->
  <component :is="Componente" :dados="dadosParaComponente" />
</template>

<script lang="ts">
import type { Component } from "vue";
import { computed, defineComponent, PropType } from "vue";

import type { ComponenteCelula, TipoTabelaCelula, TiposTabelaCelulas } from "../types-eli-tabela";
import { registryTabelaCelulas } from "./registryTabelaCelulas";

export default defineComponent({
  name: "EliTabelaCelula",
  props: {
    celula: {
      // `ComponenteCelula` é uma tupla `readonly [tipo, dados]`.
      type: Array as unknown as PropType<ComponenteCelula>,
      required: true,
    },
  },
  setup(props) {
    const tipo = computed(() => props.celula[0] as TipoTabelaCelula);
    const dados = computed(() => props.celula[1] as TiposTabelaCelulas[TipoTabelaCelula]);

    // Observação: mantemos o registry tipado, mas o TS do template não consegue
    // fazer narrowing do componente com base em `tipo`, então tipamos como `Component`.
    const Componente = computed(() => registryTabelaCelulas[tipo.value] as unknown as Component);

    const dadosParaComponente = computed(() => dados.value);

    return { Componente, dadosParaComponente };
  },
});
</script>
