使用 Typescript 的 React 组件中的默认函数值

Cha*_*lie 5 typescript reactjs asp.net-core

问题与非常相似,但我的重点是默认功能。(我是前端新手,如果有更正式的名称,请告诉我)

这是代码(我使用的是 TypeScript 2.5):

export const TestProps = {
    Hello: (name: string) => {
        console.log(name);
    }
}

type TestPropsType = typeof TestProps;

export class TestComp extends React.Component<TestPropsType, {}>{    
    public render() {
        this.props.Hello("world");
        return <div>test</div>;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当我尝试渲染此组件时:

ReactDOM.render(<TestComp />, document.getElementById("page"));
Run Code Online (Sandbox Code Playgroud)

我有这个错误?

TS2322:类型“{}”不可分配给类型“IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & ...'。类型 '{}' 不能分配给类型 'Readonly<{ Hello: (name: string) => void; }>'。

类型“{}”中缺少属性“Hello”。

我该如何解决这个问题?

Tom*_*ech 2

首先,让我们修复您的示例:

interface TestProps {
    Hello?: { (name: string): void };
}

export class TestComp extends React.Component<TestProps, {}> {    
    public static defaultProps: Partial<TestProps> = {
        Hello: name => console.log(name)
    };

    public render() {
        this.props.Hello("world");
        return <div>test</div>;
    }
}
Run Code Online (Sandbox Code Playgroud)

您之前编写的方式意味着您的组件看不到TestProps(它不是从任何地方传入的),而这Hello是必需的道具。我使用了一个接口 来Hello?使其可选,而不是使用typeof.

编译器错误来自于所需的事实Hello,因此您需要使用:

ReactDOM.render(<TestComp Hello={() => {}} />, document.getElementById("page"));
                       // ^ pass Hello as a prop here
Run Code Online (Sandbox Code Playgroud)

这样做可以修复编译错误,但仍然会出现不正确的行为,因为TestProps示例中的对象永远不会被使用。

如果您使用的是strictNullChecks,那么您将必须稍微处理一下类型系统,因为Hello是一个可选属性:

if (this.props.Hello) this.props.Hello("world");
// or
this.props.Hello && this.props.Hello("world");
Run Code Online (Sandbox Code Playgroud)

通过检查是否this.props.Hellotrue,类型被缩小为(name: string) => void | undefinedjust (name: string) => void,因此您可以调用该函数。