Napisałem kod:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Otrzymuję błąd:
Typ elementu JSX
Elem
nie ma żadnych konstrukcji ani sygnatur wywołań
Co to znaczy?
Napisałem kod:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Otrzymuję błąd:
Typ elementu JSX
Elem
nie ma żadnych konstrukcji ani sygnatur wywołań
Co to znaczy?
Odpowiedzi:
Jest to zamieszanie między konstruktorami a instancjami .
Pamiętaj, że pisząc komponent w Reakcie:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.whoToGreet}</div>;
}
}
Używasz tego w ten sposób:
return <Greeter whoToGreet='world' />;
Państwo nie używać go w ten sposób:
let Greet = new Greeter();
return <Greet whoToGreet='world' />;
W pierwszym przykładzie, jesteśmy przechodząc wokół Greeter
, w funkcji konstruktora dla naszego komponentu. To prawidłowe użycie. W drugim przykładzie, jesteśmy przechodząc wokół jest wystąpienie o Greeter
. To jest niepoprawne i zakończy się niepowodzeniem w czasie wykonywania z błędem typu „Obiekt nie jest funkcją”.
Problem z tym kodem
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
jest to, że spodziewa się wystąpienie o React.Component
. Co chcesz funkcję, która pobiera konstruktora dla React.Component
:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
lub podobnie:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}
function renderGreeting(Elem: typeof React.Component)
w ES6?
function renderGreeting (Elem: new() => React.SFC<any>){...}
jeśli tak, to dlaczego deklarujemy typ KŁŻ w ten sposób: const Hello:React.SFC<any> = (props) => <div>Hello World</div>
a nie: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; };
Otrzymuję błąd „Typ właściwości” nie istnieje w typie „Typ składnika”.
Jeśli chcesz wziąć klasę komponentu jako parametr (a nie instancję), użyj React.ComponentClass
:
function renderGreeting(Elem: React.ComponentClass<any>) {
return <span>Hello, <Elem />!</span>;
}
React.ComponentType<any>
typu zamiast uwzględniać je.
Kiedy konwertuję z JSX na TSX i zachowujemy niektóre biblioteki jako js / jsx, a inne konwertujemy na ts / tsx, prawie zawsze zapominam o zmianie instrukcji importu js / jsx w plikach TSX \ TS z
import * as ComponentName from "ComponentName";
do
import ComponentName from "ComponentName";
Jeśli wywołujesz stary komponent w stylu JSX (React.createClass) z TSX, użyj
var ComponentName = require("ComponentName")
tsconfig.json
) na allowSyntheticDefaultImports
. Zobacz: typescriptlang.org/docs/handbook/compiler-options.html i dyskusję tutaj: blog.jonasbandi.net/2016/10/...
Jeśli naprawdę nie obchodzą cię rekwizyty, to najszerszy z możliwych jest React.ReactType
.
Umożliwiłoby to przekazywanie natywnych elementów dom jako ciągów. React.ReactType
obejmuje wszystkie te:
renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
render() {
return 'Hello, World!'
}
});
Jeśli używasz material-ui , przejdź do definicji typu komponentu, która jest podkreślana przez TypeScript. Najprawdopodobniej zobaczysz coś takiego
export { default } from './ComponentName';
Masz dwie możliwości rozwiązania tego błędu:
1. Dodaj .default
podczas korzystania z komponentu w JSX:
import ComponentName from './ComponentName'
const Component = () => <ComponentName.default />
2. Zmień nazwę eksportowanego komponentu na „domyślną” podczas importowania:
import { default as ComponentName } from './ComponentName'
const Component = () => <ComponentName />
W ten sposób nie musisz określać za .default
każdym razem, gdy używasz komponentu.
U mnie zadziałało: https://github.com/microsoft/TypeScript/issues/28631#issuecomment-472606019 Naprawiam to, robiąc coś takiego:
const Component = (isFoo ? FooComponent : BarComponent) as React.ElementType
W moim przypadku używałem React.ReactNode
jako typu dla komponentu funkcjonalnego zamiast React.FC
typu.
W tym komponencie, aby być dokładnym:
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>
}
/>
)
}
Jak wspomniał @Jthorpe, ComponentClass
zezwala tylko Component
lub PureComponent
ale nie FunctionComponent
.
Jeśli spróbujesz przekazać a FunctionComponent
, maszynopis zwróci błąd podobny do ...
Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.
Jednak używając ComponentType
zamiast ComponentClass
zezwalać w obu przypadkach. W pliku deklaracji reakcji typ jest zdefiniowany jako ...
type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>
W moim przypadku brakowało mi new
w definicji typu.
some-js-component.d.ts
plik:
import * as React from "react";
export default class SomeJSXComponent extends React.Component<any, any> {
new (props: any, context?: any)
}
i wewnątrz tsx
pliku, w którym starałem się importować bez typu komponent:
import SomeJSXComponent from 'some-js-component'
const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />
Deklarując komponent klasy React, użyj React.ComponentClass
zamiast React.Component
tego, naprawi to błąd ts.
Możesz użyć
function renderGreeting(props: {Elem: React.Component<any, any>}) {
return <span>Hello, {props.Elem}!</span>;
}
Jednak czy poniższe rozwiązania działają?
function renderGreeting(Elem: React.ComponentType) {
const propsToPass = {one: 1, two: 2};
return <span>Hello, <Elem {...propsToPass} />!</span>;
}
@types/react
ich używasz , najłatwiej jest z nich korzystaćfunction RenderGreeting(Elem: React.ComponentType) { ... }