Обновлено для TypeScript 2.1
TypeScript 2.1 теперь поддерживает распространение/отдых объектов, поэтому обходных путей больше не требуется!
Оригинальный вопрос
TypeScript поддерживает атрибуты распространения JSX, которые обычно используются в React для передачи атрибутов HTML из компонента в визуализированный элемент HTML:
interface LinkProps extends React.HTMLAttributes {
textToDisplay: string;
}
class Link extends React.Component<LinkProps, {}> {
public render():JSX.Element {
return (
<a {...this.props}>{this.props.textToDisplay}</a>
);
}
}
<Link textToDisplay="Search" href="#" onclick="location.href='http://google.com'; return false;" />
Однако React ввел предупреждение , если вы передаете какой-либо неизвестный реквизит элементу HTML. Приведенный выше пример выдаст предупреждение времени выполнения React о том, что textToDisplay
является неизвестной опорой <a>
. Предлагаемое решение для случая, подобного этому, состоит в том, чтобы использовать свойства покоя объекта для извлечения ваших пользовательских реквизитов и использовать остальное для атрибутов распространения JSX:
const {textToDisplay, ...htmlProps} = this.props;
return (
<a {...htmlProps}>{textToDisplay}</a>
);
Но TypeScript пока не поддерживает этот синтаксис. Я знаю, что, надеюсь, когда-нибудь мы сможем сделать это в TypeScript. (Обновление: TS 2.1 теперь поддерживает распространение/отдых объектов! Почему ты все еще читаешь это?) А пока какие обходные пути есть? Я ищу решение, которое не ставит под угрозу безопасность типов, и нахожу его на удивление трудным. Например, я мог бы сделать это:
const customProps = ["textDoDisplay", "otherCustomProp", "etc"];
const htmlProps:HTMLAttributes = Object.assign({}, this.props);
customProps.forEach(prop => delete htmlProps[prop]);
Но для этого необходимо использовать имена строковых свойств, которые не проверяются на соответствие фактическим реквизитам и поэтому подвержены опечаткам и плохой поддержке IDE. Есть ли лучший способ сделать это?