ฉันเขียนรหัสบางส่วน:
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
ของ ไม่ถูกต้องและจะล้มเหลวขณะทำงานโดยมีข้อผิดพลาดเช่น "Object is not a function"
ปัญหาเกี่ยวกับรหัสนี้
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>){...}
ถ้าอย่างนั้นทำไมเราถึงประกาศประเภทของ SFCs แบบนี้: 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; };
ฉันได้รับข้อผิดพลาด "Property" type "ไม่มีอยู่ในประเภท" typeof Component ""
หากคุณต้องการใช้คลาสองค์ประกอบเป็นพารามิเตอร์ (เทียบกับอินสแตนซ์) ให้ใช้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
ไป ดู: typescriptlang.org/docs/handbook/compiler-options.html และการอภิปรายที่นี่: blog.jonasbandi.net/2016/10/30
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';
คุณมี 2 ตัวเลือกในการแก้ไขข้อผิดพลาด:
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/issues/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
, typescript จะโยนข้อผิดพลาดคล้ายกับ ...
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) { ... }