2015-09-30 34 views
17

Tôi đang sử dụng React.js với TypeScript. Có cách nào để tạo ra các thành phần React thừa hưởng từ các thành phần khác nhưng có một số đạo cụ/tiểu bang bổ sung không?Mở rộng các thành phần React trong TypeScript

Những gì tôi đang cố gắng để đạt được là một cái gì đó như thế này:

interface BaseStates { 
    a: number; 
} 

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    protected getBaseInitialState(): BaseStates { 
     return { a: 3 }; 
    } 
} 

class Base extends GenericBase<BaseStates> { 
    getInitialState(): BaseStates { 
     return super.getBaseInitialState(); 
    } 
} 

interface DerivedStates extends BaseStates { 
    b: number; 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState(): DerivedStates { 
     var initialStates = super.getBaseInitialState() as DerivedStates; // unsafe?? 
     initialStates.b = 4; 
     return initialStates 
    } 
} 

Tuy nhiên, điều này sẽ thất bại nếu tôi gọi this.setState trong Derived, tôi nhận được một lỗi đánh máy (thông số của loại DerivedStates không thể chuyển nhượng để gõ S). Tôi cho rằng đây không phải là một điều cụ thể của TypeScript, nhưng là một hạn chế chung của việc trộn lẫn thừa kế với Generics (?). Có cách giải quyết an toàn kiểu nào cho việc này không?

CẬP NHẬT

Các giải pháp tôi giải quyết trên (dựa trên câu trả lời của David Sherret):

interface BaseStates { 
    a: number; 
} 

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    constructor() { 
     super(); 
     this.state = this.getInitialState(); 
    } 

    getInitialState(): S { 
     return { a: 3 } as S; 
    } 

    update() { 
     this.setState({ a: 7 } as S); 
    } 
} 

interface DerivedStates extends BaseStates { 
    b: number; 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState(): DerivedStates { 
     var initialStates = super.getInitialState(); 
     initialStates.b = 4; 
     return initialStates; 
    } 

    update() { 
     this.setState({ a: 7, b: 4 }); 
    } 
} 

Trả lời

10

Bạn có thể thiết lập chỉ có một vài tính chất của nhà nước cùng một lúc trong Derived bằng cách sử dụng một xác nhận loại:

this.setState({ b: 4 } as DerivedStates); // do this 
this.setState({ a: 7 } as DerivedStates); // or this 
this.setState({ a: 7, b: 4 });   // or this 

Nhân tiện, không cần phải có các tên khác nhau cho getInitialState ... bạn chỉ có thể làm:

class GenericBase<S extends BaseStates> extends React.Component<void, S> { 
    constructor() { 
     super();   
     this.state = this.getInitialState(); 
    } 

    protected getInitialState() { 
     return { a: 3 } as BaseStates as S; 
    } 
} 

class Derived extends GenericBase<DerivedStates> { 
    getInitialState() { 
     var initialStates = super.getInitialState(); 
     initialStates.b = 4; 
     return initialStates; 
    } 
} 
+0

Cảm ơn câu trả lời nhanh. Đối với giải pháp của bạn, tôi nhận được lỗi cho dòng thứ hai của hàm tạo: 'loại 'BaseStates' không thể gán để nhập 'S'' không đáng ngạc nhiên, vì' S' là một phân lớp của 'BaseStates' . – Thegaram

+0

@Thegaram tôi vừa sửa lỗi đó. Đã sửa lỗi. –

+0

Cảm ơn! Vẫn không chắc chắn về mức độ an toàn của những chương trình này, nhưng câu hỏi của tôi đã được trả lời. – Thegaram

Các vấn đề liên quan