39 lines
1.4 KiB
Vue
39 lines
1.4 KiB
Vue
<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>
|