Tôi đã viết một số mã:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Tôi đang gặp lỗi:
Kiểu phần tử JSX
Elem
không có bất kỳ chữ ký cấu trúc hoặc cuộc gọi nào
Nó có nghĩa là gì?
Tôi đã viết một số mã:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Tôi đang gặp lỗi:
Kiểu phần tử JSX
Elem
không có bất kỳ chữ ký cấu trúc hoặc cuộc gọi nào
Nó có nghĩa là gì?
Câu trả lời:
Đây là một sự nhầm lẫn giữa các nhà xây dựng và các trường hợp .
Hãy nhớ rằng khi bạn viết một thành phần trong React:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.whoToGreet}</div>;
}
}
Bạn sử dụng nó theo cách này:
return <Greeter whoToGreet='world' />;
Bạn không sử dụng nó theo cách này:
let Greet = new Greeter();
return <Greet whoToGreet='world' />;
Trong ví dụ đầu tiên, chúng ta đi xung quanh Greeter
, hàm tạo cho thành phần của chúng ta. Đó là cách sử dụng đúng. Trong ví dụ thứ hai, chúng ta chuyển qua một thể hiện của Greeter
. Điều đó không chính xác và sẽ thất bại khi chạy với lỗi như "Object không phải là hàm".
Vấn đề với mã này
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
là nó chờ đợi một ví dụ của React.Component
. Những gì bạn muốn một hàm có một hàm tạo cho React.Component
:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
hoặc tương tự:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}
function renderGreeting(Elem: typeof React.Component)
trong ES6?
function renderGreeting (Elem: new() => React.SFC<any>){...}
Nếu vậy tại sao chúng ta tuyên bố loại SFC như thế này: const Hello:React.SFC<any> = (props) => <div>Hello World</div>
và không: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; };
Tôi đang gặp lỗi "Thuộc tính 'loại' không tồn tại trên loại 'loại thành phần'".
Nếu bạn muốn lấy một lớp thành phần làm tham số (so với một thể hiện), hãy sử dụng React.ComponentClass
:
function renderGreeting(Elem: React.ComponentClass<any>) {
return <span>Hello, <Elem />!</span>;
}
React.ComponentType<any>
loại thay vì để bao gồm chúng.
Khi tôi chuyển đổi từ JSX sang TSX và chúng tôi giữ một số thư viện dưới dạng js / jsx và chuyển đổi các thư viện khác thành ts / tsx, tôi hầu như luôn quên thay đổi các câu lệnh nhập js / jsx trong các tệp TSX \ TS từ
import * as ComponentName from "ComponentName";
đến
import ComponentName from "ComponentName";
Nếu gọi một thành phần kiểu JSX (React.createClass) cũ từ TSX, thì hãy sử dụng
var ComponentName = require("ComponentName")
tsconfig.json
) thành allowSyntheticDefaultImports
. Xem: typescriptlang.org/docs/handbook/compiler-options.html và thảo luận ở đây: blog.jonasbandi.net/2016/10/...
Nếu bạn thực sự không quan tâm đến đạo cụ thì loại rộng nhất có thể là React.ReactType
.
Điều này sẽ cho phép chuyển các phần tử dom gốc dưới dạng chuỗi. React.ReactType
bao gồm tất cả những điều này:
renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
render() {
return 'Hello, World!'
}
});
Nếu bạn đang sử dụng vật liệu-ui , hãy chuyển đến định nghĩa kiểu của thành phần đang được TypeScript gạch chân. Nhiều khả năng bạn sẽ thấy một cái gì đó như thế này
export { default } from './ComponentName';
Bạn có 2 tùy chọn để khắc phục lỗi:
1.Thêm .default
khi sử dụng thành phần trong JSX:
import ComponentName from './ComponentName'
const Component = () => <ComponentName.default />
2. Đặt tên cho thành phần đang được xuất thành "mặc định" khi nhập:
import { default as ComponentName } from './ComponentName'
const Component = () => <ComponentName />
Bằng cách này, bạn không cần chỉ định .default
mỗi khi bạn sử dụng thành phần.
Cách sau đây có hiệu quả với tôi: https://github.com/microsoft/TypeScript/issues/28631#issuecomment-472606019 Tôi sửa nó bằng cách làm như thế này:
const Component = (isFoo ? FooComponent : BarComponent) as React.ElementType
Trong trường hợp của tôi, tôi đã sử dụng React.ReactNode
như một loại cho một thành phần chức năng thay vì React.FC
loại.
Trong thành phần này là chính xác:
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>
}
/>
)
}
Như @Jthorpe đã ám chỉ, ComponentClass
chỉ cho phép Component
hoặc PureComponent
không FunctionComponent
.
Nếu bạn cố gắng vượt qua a FunctionComponent
, bản thảo sẽ đưa ra một lỗi tương tự như ...
Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.
Tuy nhiên, bằng cách sử dụng ComponentType
chứ không phải ComponentClass
bạn cho phép cả hai trường hợp. Theo tệp khai báo phản ứng, loại được xác định là ...
type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>
Trong trường hợp của tôi, tôi đã bị mất new
trong định nghĩa loại.
some-js-component.d.ts
tập tin:
import * as React from "react";
export default class SomeJSXComponent extends React.Component<any, any> {
new (props: any, context?: any)
}
và bên trong tsx
tệp nơi tôi đang cố gắng nhập thành phần chưa được gõ:
import SomeJSXComponent from 'some-js-component'
const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />
Khi khai báo thành phần React Class, sử dụng React.ComponentClass
thay vì React.Component
sau đó nó sẽ sửa lỗi ts.
Bạn có thể dùng
function renderGreeting(props: {Elem: React.Component<any, any>}) {
return <span>Hello, {props.Elem}!</span>;
}
Tuy nhiên, có làm việc sau đây?
function renderGreeting(Elem: React.ComponentType) {
const propsToPass = {one: 1, two: 2};
return <span>Hello, <Elem {...propsToPass} />!</span>;
}
@types/react
chúng thì dễ sử dụng nhấtfunction RenderGreeting(Elem: React.ComponentType) { ... }