Я написав код:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Я отримую помилку:
Тип елемента JSX
Elem
не має жодної конструкції та підписів виклику
Що це означає?
Я написав код:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Я отримую помилку:
Тип елемента JSX
Elem
не має жодної конструкції та підписів виклику
Що це означає?
Відповіді:
Це плутанина між конструкторами та екземплярами .
Пам'ятайте, що коли ви пишете компонент в React:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.whoToGreet}</div>;
}
}
Ви використовуєте це таким чином:
return <Greeter whoToGreet='world' />;
Ви не використовуєте це таким чином:
let Greet = new Greeter();
return <Greet whoToGreet='world' />;
У першому прикладі, ми проходимо навколо Greeter
, в функцію конструктора для нашого компонента. Це правильне використання. У другому прикладі, ми проходимо навколо екземпляра з Greeter
. Це неправильно, і він не працює під час виконання з помилкою типу "Об'єкт не є функцією".
Проблема з цим кодом
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
є те , що він очікує екземпляр з React.Component
. Що ви хочете, функція, яка бере конструктор для React.Component
:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
або аналогічно:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}
function renderGreeting(Elem: typeof React.Component)
в ES6?
function renderGreeting (Elem: new() => React.SFC<any>){...}
якщо так, то чому ми оголошуємо тип SFC так:, const Hello:React.SFC<any> = (props) => <div>Hello World</div>
а не:const Hello: new() =>React.SFC<any> = (props) => <div>Hello World</div>
export const BackNavigationTextWrapper = (WrappedComponent: typeof React.Component) => { const BackNavigationTextWrappedComponent = (props, { commonElements = {} }: any) => { return <WrappedComponent {...props} backLabel={commonElements.backLabel || 'Go back to reservation details'} /> }; BackNavigationTextWrappedComponent.type = WrappedComponent.type; return BackNavigationTextWrappedComponent; };
Я отримую помилку "Властивості" тип "не існує для типу" typeof Компонент "".
Якщо ви хочете взяти клас компонента як параметр (проти екземпляра), використовуйте React.ComponentClass
:
function renderGreeting(Elem: React.ComponentClass<any>) {
return <span>Hello, <Elem />!</span>;
}
React.ComponentType<any>
тип, а не для їх включення.
Коли я перетворюю з JSX в TSX, і ми зберігаємо одні бібліотеки як js / jsx і перетворюємо інші на ts / tsx, я майже завжди забуваю змінити js / jsx імпорт заяв у файлах TSX \ TS з
import * as ComponentName from "ComponentName";
до
import ComponentName from "ComponentName";
Якщо ви викликаєте старий компонент стилю JSX (React.createClass) з TSX, тоді використовуйте
var ComponentName = require("ComponentName")
tsconfig.json
) на allowSyntheticDefaultImports
. Дивіться: typecriptlang.org/docs/handbook/compiler-options.html та обговорення тут: blog.jonasbandi.net/2016/10/…
Якщо ви дійсно не дбаєте про реквізит, то це найширший тип React.ReactType
.
Це дозволило б передати рідні елементи dom як рядки. React.ReactType
охоплює все це:
renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
render() {
return 'Hello, World!'
}
});
Якщо ви використовуєте material-ui , перейдіть до визначення типу компонента, який підкреслюється TypeScript. Швидше за все, ви побачите щось подібне
export { default } from './ComponentName';
У вас є два варіанти вирішення помилки:
1.Додайте .default
при використанні компонента в JSX:
import ComponentName from './ComponentName'
const Component = () => <ComponentName.default />
2.Призначте при імпорті компонент, який експортується як "за замовчуванням":
import { default as ComponentName } from './ComponentName'
const Component = () => <ComponentName />
Таким чином, вам не потрібно вказувати .default
кожен раз, коли ви використовуєте компонент.
Для мене працювало наступне: https://github.com/microsoft/TypeScript/isissue/28631#issuecomment-472606019 Я це виправляю, роблячи щось подібне:
const Component = (isFoo ? FooComponent : BarComponent) as React.ElementType
У моєму випадку я використовував React.ReactNode
як тип для функціонального компонента замість React.FC
типу.
У цьому компоненті, щоб бути точним:
export const PropertiesList: React.FC = (props: any) => {
const list:string[] = [
' Consequat Phasellus sollicitudin.',
' Consequat Phasellus sollicitudin.',
'...'
]
return (
<List
header={<ListHeader heading="Properties List" />}
dataSource={list}
renderItem={(listItem, index) =>
<List.Item key={index}> {listItem } </List.Item>
}
/>
)
}
Як нагадав @Jthorpe, ComponentClass
дозволяє лише те, чи Component
ні, PureComponent
але не FunctionComponent
.
Якщо ви спробуєте передати A FunctionComponent
, typecript видасть помилку, схожу на ...
Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.
Однак, використовуючи ComponentType
, ніж ComponentClass
ви дозволяєте, в обох випадках. У файлі декларації про реакцію тип визначається як ...
type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>
У моєму випадку я бракував new
усередині визначення типу.
some-js-component.d.ts
файл:
import * as React from "react";
export default class SomeJSXComponent extends React.Component<any, any> {
new (props: any, context?: any)
}
і всередині tsx
файлу, куди я намагався імпортувати нетипізований компонент:
import SomeJSXComponent from 'some-js-component'
const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />
При оголошенні компонента React Class використовуйте React.ComponentClass
замість React.Component
цього він виправить помилку ts.
Можна використовувати
function renderGreeting(props: {Elem: React.Component<any, any>}) {
return <span>Hello, {props.Elem}!</span>;
}
Однак чи працює наступне?
function renderGreeting(Elem: React.ComponentType) {
const propsToPass = {one: 1, two: 2};
return <span>Hello, <Elem {...propsToPass} />!</span>;
}
@types/react
ними, найпростіше використовуватиfunction RenderGreeting(Elem: React.ComponentType) { ... }