javascript - O objeto é do tipo 'unknown'.ts(2571) em componente genérico
Eu tenho um componente Table com genéricos e uso um componente estático dentro da Table para compor colunas, também com genéricos.
O problema é que eu gostaria que o componente Column herdasse o tipo genérico passado para a Tabela ao executar a função de dados, que recebe o resultado passado para ele.
Eu sei que digitar explicitamente funcionará, por exemplo:
<Table.Column<TableItem> data={(item) => item.name} />A verdadeira questão é: É possível realizar essa inferência de tipo a partir do meu componente Table e passá-la para o componente estático Column? Para que eu não precise adicionar o tipo explicitamente a cada coluna...
SANDBOX PARA REPRODUZIR, APENAS COMPONENTES DE TABELA E COLUNA:
https://codesandbox.io/s/generic-table-column-r54lh?file=/src/App.tsx
Resposta #1
Você pode especificar o tipo para item:
<Table.Column<TableItem> data={(item:[type goes here]) => item.name} />
Poucos exemplos:
<Table.Column<TableItem> data={(item:any) => item.name} />
// or even
<Table.Column<TableItem> data={(item:{name:string;}) => item.name} />
Resposta #2
Há um problema em sua tipagem de children, a saber, que você está usando ReactElement, que não inclui a tipagem para a função JSX real, apenas para o elemento retornado. Você pode ver isso em seu exemplo, notando que os seguintes children covariantes e contravariantes passam, apesar da sua tipagem de children:
const MyDiv = (props:{myProp:string})=><div>{props.myProp}</div>
const App = () => {
return (
<Table<TableItem> keyExtractor={(item) => item.id} values={items}>
<Table.Column header="Name" data={(item) => item.name} />
<Table.Column header="Surname" data={(item) => item.surname} />
<MyDiv myProp="me" />
<div />
</Table>
);
};
MAS... Eu não acho que esse seja realmente o seu problema subjacente. O problema realmente é que você quer que o Typescript verifique se seus componentes filhos são realmente criados através de JSX específico com props específicos, mas, na verdade, tudo o que o Typescript fará atualmente é verificar se o seu JSX retorna um JSX.Element válido. Ele não verificará se a função que gerou esse JSX.Element satisfaz um tipo particular ou se o tipo de retorno dessa função é um tipo específico de elemento com props específicos.
Esta é uma limitação de design que é discutida nesta questão aberta.
Acho que você poderia contornar isso basicamente definindo sua própria prop personalizada que recebesse as props de Table.Column e então as passasse para Table.Column dentro do seu componente Table. Por exemplo, algo como columnProps: ColumnProps<T> como uma prop do Table. No entanto, não tenho certeza se isso seria mais fácil do que apenas fornecer o tipo explícito para Table.Column.
