ค้นหาเว็บไซต์

javascript - วิธีขยายคลาส React ใน typescript


นี่คือตัวอย่างง่ายๆ:

interface BaseProps {
    name: string;
}

class BaseClass<P extends BaseProps> extends React.Component<P, void> {

}

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {

} 

ฉันคาดหวังว่า SuperClass จะมี this.props.name โดยค่าเริ่มต้น แต่ตอนนี้ฉันได้รับข้อผิดพลาดในการคอมไพล์ โดยบอกว่า Type 'SuperProps' does not satisfy the constraint 'BaseProps'. Property 'name' is missing in type 'SuperProps'.

ฉันทำอะไรผิดหรือเปล่า? ฉันเข้าใจว่าฉันสามารถทำ SuperProps extends BaseProps ได้ แต่ดูเหมือนว่าที่นี่จะซ้ำซ้อน.

คำตอบ #1

class BaseClass<P extends BaseProps> extends React.Component<P, void>

ที่ <P extends BaseProps> หมายถึงชนิดใด ๆ ที่ถูกต้องซึ่งขยาย BaseProps สามารถกำหนดค่าให้กับ BaseClass ได้ นี่คือวิธีที่เจนเนอริกทำงาน

ตอนนี้ เมื่อคุณทำ

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {

} 

คุณกำลังกำหนดประเภท SuperProps ซึ่งไม่ได้สืบทอดจาก BaseProps นั่นคือเหตุผลที่คุณได้รับข้อผิดพลาด

ในการแก้ไขข้อผิดพลาด ตามที่คุณบอก คุณจำเป็นต้องขยายอินเทอร์เฟซ BaseProps หรือคุณสามารถใช้ชนิด intersection ถ้าคุณใช้ชนิด intersection ตัวอย่างสมบูรณ์จะมีลักษณะดังนี้:

export interface BaseProps {
    name: string;
}

class BaseClass<P> extends React.Component<P & BaseProps, void> {

}

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {
    render(): JSX.Element {
        return (
            <div>
                {this.props.name} {/* Won't throw an error*/}
            </div>
        );
    }
}

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับประเภทขั้นสูงได้ที่นี่

คำตอบ #2

ตอนนี้ลองพูดว่าคุณไม่สามารถแก้ไข BaseClass (โค้ดของบุคคลที่สาม) ให้รองรับชนิดทั่วไปได้ เช่น

class BaseClass extends React.Component<BaseProps, void> {

}

คุณยังคงสามารถนิยามใหม่ BaseClass ด้วยประเภทพร็อพที่ขยายออกไปได้ดังนี้:

const SuperClass = BaseClass as React.ComponentClass<
  BaseProps & {
    somethingElse: string;
  }
>;

ตัวอย่างเต็ม เช่น ที่ SomeInput จริงๆ รองรับ prop autoFocus แต่ type defs ของ prop ที่ส่งออกไม่รองรับ:

import { Input as SomeInput, InputPropsType as SomeInputPropsType } from 'somewhere';

const Input = SomeInput as React.ComponentClass<
  SomeInputPropsType & {
    autoFocus?: boolean;
  }
>;

// Now passing `autoFocus` prop to `Input` should be fine

บทความที่เกี่ยวข้อง