Я пытался исправить некоторые типы, относящиеся к DataTable, на углерод-компоненты-реагируют, но застрял при создании одного свойства необязательным. Я дошел до того, что создал свою собственную демонстрацию, чтобы показать эту проблему:
import React from "react";
interface Human {
name: string;
age: number;
address?: string;
}
interface ButtonProps<R extends Human> {
name: R["name"];
age: R["age"];
address?: R["address"];
onClick?: Function;
}
interface RenderProps<R extends Human> {
human: R;
getButtonProps(data?: ButtonProps<R>): ButtonProps<R>;
}
export interface DataTableProps<R extends Human> {
rows: R[];
render(props: RenderProps<R>): React.ReactNode;
}
class DataTable<R extends Human> extends React.Component<DataTableProps<R>> {
render() {
return this.props.rows.map((h) => {
const buttonProps: () => Human = () => ({ ...h }); // This is only to be able to see the type of buttonProps in IDE
return this.props.render({ human: h, getButtonProps: buttonProps });
});
}
}
interface TableButtonProps {
name: string;
address?: string;
}
const TableButton = (props: TableButtonProps) => (
<button>Button for {props.name}</button>
);
export const Demo = () => {
// This works
const man1: Human = {
name: "Anna",
age: 30,
};
// This seems to be ok since "address" is optional
// but this isn't working!
const man2 = {
name: "Tom",
age: 32,
};
// This works
const man3 = {
name: "John",
age: 40,
address: "404 Street Unknown",
};
return (
<DataTable
rows={[man2]}
render={({ getButtonProps }) => {
return <TableButton {...getButtonProps()} />;
}}
></DataTable>
);
};
Ошибка, которую я получаю при TableButton:
Type '{ name: string; age: number; address?: unknown; onClick?: Function | undefined; }' is not assignable to type 'TableButtonProps'.
Types of property 'address' are incompatible.
Type 'unknown' is not assignable to type 'string | undefined'.
Type 'unknown' is not assignable to type 'string'. TS2322
Свойство address
имеет unknown
введите по какой-то причине. Когда я использую синтаксис, такой как man1
или man3
, все работает, вы можете заменить его на rows=
. Почему man2
не работает, хотя тип по-прежнему настроен на расширение Human? Потерян ли TypeScript?
Вы можете проверить это, инициализировав проект с помощью npx create-react-app mydemo --template=typescript
// Редактировать:
interface ButtonProps<R extends Human> {
name: Human["name"];
age: Human["age"];
address?: Human["address"];
onClick?: Function;
}
Также, похоже, эта проблема решается и " защита "address
тип.