2015-10-18 2 views
2

Вот пример, иллюстрирующий проблему:Почему машинопись компилятор оленья кожа позволяют возвращать экземпляр класса

Сначала я машинопись определение для React, где у нас есть определение для компонента:

class Component<P, S> implements ComponentLifecycle<P, S> { 
    static propTypes: ValidationMap<any>; 
    static contextTypes: ValidationMap<any>; 
    static childContextTypes: ValidationMap<any>; 
    static defaultProps: Props<any>; 

    constructor(props?: P, context?: any); 
    setState(f: (prevState: S, props: P) => S, callback?:() => any): void; 
    setState(state: S, callback?:() => any): void; 
    forceUpdate(callBack?:() => any): void; 
    render(): JSX.Element; 
    props: P; 
    state: S; 
    context: {}; 
    refs: { 
     [key: string]: Component<any, any> 
    }; 
} 

Затем в приложении я создал класс, который расширяет компонент.

class App extends React.Component<any, any> { 
} 

И хотел бы иметь функцию, которая возвращает экземпляр компонента.

function Test<T extends React.Component<any, any>>(): T 
{ 
    return App; 
} 

Составитель машинописного машиностроения не позволяет мне это делать. Ошибка:

Свойство «SetState» отсутствует в типе «TypeOf App»

Я не понимаю, потому что класс должен наследовать все от Component.

ответ

4

Может быть, вы должны написать

function Test<T extends React.Component<any, any>>(): T 
{ 
    return new App(); 
} 
0

Правильно! Это был очень длинный день для меня.

Я все еще ничего не понимаю. Я ТСД для реакции-перевождь со следующими определениями:

export interface ClassDecorator { 
    <T extends ComponentLifecycle<any, any>>(target:T): T; 
} 

export function connect(mapStateToProps?: MapStateToProps, 
          mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject, 
          mergeProps?: MergeProps, 
          options?: Options): ClassDecorator; 

А в другой файл, где я использую его у меня есть

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(App); 

И это работает. Почему мне не нужно передавать новое приложение()? Приложение - это тот же класс, что и в первом вопросе. ComponentLifecycle - это интерфейс, реализованный React.Component. Когда я меняю ComponentLifecycle на Component в tsd-файле, мой код не компилируется.

+0

Реагирующие компоненты всегда передаются как * конструкторские функции *, а не экземпляры классов. Вы никогда не должны писать 'new App()' в коде пользователя. React - это библиотека, отвечающая за управление экземпляром класса. –

+0

Я знаю, что я не должен создавать экземпляры React Components. Проблема в том, что я не знаю, почему я могу передать конструкторную функцию React Component в качестве аргумента метода в этом конкретном примере и почему я не могу этого сделать, когда я изменяю определение из ComponentLifecycle на компонент . Компонент - это класс, а ComponentLifecycle - это интерфейс, но он не имеет значения здесь – niba

+0

Хорошо. Я нашел проблему. Интерфейс ComponentLifecycle имеет только необязательные типы внутри определения. Это приводит к тому, что компилятор позволяет передать функцию конструктора. – niba

Смежные вопросы